home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / cfengine-1.5.3 / src / install.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-24  |  102.9 KB  |  4,738 lines

  1. /* cfengine for GNU
  2.  
  3.         Copyright (C) 1995
  4.         Free Software Foundation, Inc.
  5.  
  6.    This file is part of GNU cfengine - written and maintained 
  7.    by Mark Burgess, Dept of Computing and Engineering, Oslo College,
  8.    Dept. of Theoretical physics, University of Oslo
  9.  
  10.    This program is free software; you can redistribute it and/or modify it
  11.    under the terms of the GNU General Public License as published by the
  12.    Free Software Foundation; either version 2, or (at your option) any
  13.    later version.
  14.  
  15.    This program is distributed in the hope that it will be useful,
  16.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.    GNU General Public License for more details.
  19.  
  20.   You should have received a copy of the GNU General Public License
  21.   along with this program; if not, write to the Free Software
  22.   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
  23.  
  24. */
  25.  
  26.  
  27. /*******************************************************************/
  28. /*                                                                 */
  29. /* Routines which install actions parsed by the parser             */
  30. /*                                                                 */
  31. /* Derived from parse.c (Parse object)                             */
  32. /*                                                                 */
  33. /*******************************************************************/
  34.  
  35. #define INET
  36.  
  37. #include "cf.defs.h"
  38. #include "cf.extern.h"
  39.  
  40. /*******************************************************************/
  41.  
  42. InstallLocalInfo (varvalue)
  43.  
  44. char *varvalue;
  45.  
  46. { int number = -1;
  47.   char buffer[maxvarsize], command[maxvarsize], *sp;
  48.   char value[bufsize];
  49.   
  50. if ( ! IsInstallable(CLASSBUFF))
  51.    {
  52.    Debug1("Not installing %s, no match\n",value);
  53.    return;
  54.    }
  55.  
  56. bzero(value,bufsize);
  57.  
  58. ExpandVarstring(varvalue,value,NULL);
  59.  
  60. if (strncmp(value,"exec ",5) == 0)
  61.    {
  62.    for (sp = value+4; *sp == ' '; sp++)
  63.       {
  64.       }
  65.  
  66.    if (*sp == '/')
  67.       {
  68.       strncpy(command,sp,maxvarsize);
  69.       GetExecOutput(command,value);
  70.       Chop(value);
  71.       value[maxvarsize-1] = '\0';  /* Truncate to maxvarsize */
  72.       }
  73.    else
  74.       {
  75.       Warning("Exec string in control did not specify an absolute path");
  76.       }
  77.    }
  78.  
  79. Debug1("\n(Action is control, storing variable [%s=%s])\n",CURRENTITEM,value);
  80.  
  81. switch (ScanVariable(CURRENTITEM))
  82.    {
  83.    case cfsite:
  84.    case cffaculty:  if (!IsDefinedClass(CLASSBUFF))
  85.                       {
  86.               break;
  87.               }
  88.  
  89.                     if (VFACULTY[0] != '\0')
  90.                        {
  91.                        yyerror("Multiple declaration of variable faculty / site");
  92.                        FatalError("Redefinition of basic system variable");
  93.                        }
  94.  
  95.                     strcpy(VFACULTY,value);
  96.                     break;
  97.  
  98.    case cfdomain:  if (!IsDefinedClass(CLASSBUFF))
  99.                       {
  100.               break;
  101.               }
  102.  
  103.                    strcpy(VDOMAIN,value);
  104.           
  105.            if (!strstr(VSYSNAME.nodename,ToLowerStr(VDOMAIN)))
  106.               {
  107.               sprintf(VFQNAME,"%s.%s",VSYSNAME.nodename,ToLowerStr(VDOMAIN));
  108.               strcpy(VUQNAME,VSYSNAME.nodename);
  109.               }
  110.            else
  111.               {
  112.               int n = 0;
  113.               strcpy(VFQNAME,VSYSNAME.nodename);
  114.               
  115.               while(VSYSNAME.nodename[n++] != '.')
  116.             {
  117.             }
  118.  
  119.                       strncpy(VUQNAME,VSYSNAME.nodename,n-1);              
  120.                }
  121.            
  122.            if (! NOHARDCLASSES)
  123.               {
  124.               if (strlen(VFQNAME) > maxvarsize-1)
  125.              {
  126.               FatalError("The fully qualified name is longer than maxvarsize!!");
  127.              }
  128.              
  129.               strcpy(buffer,VFQNAME);
  130.              
  131.               AddClassToHeap(CanonifyName(buffer));
  132.               }
  133.                    break;
  134.  
  135.    case cfsysadm:  /* Can be redefined */
  136.                    if (!IsDefinedClass(CLASSBUFF))
  137.                       {
  138.               break;
  139.               }
  140.  
  141.                   strcpy(VSYSADM,value);
  142.                   break;
  143.  
  144.    case cfnetmask:
  145.                    if (!IsDefinedClass(CLASSBUFF))
  146.                       {
  147.               break;
  148.               }
  149.  
  150.                   if (VNETMASK[0] != '\0')
  151.                      {
  152.                      yyerror("Multiple declaration of variable netmask");
  153.                      FatalError("Redefinition of basic system variable");
  154.                      }
  155.                   strcpy(VNETMASK,value);
  156.                   break;
  157.  
  158.  
  159.    case cfmountpat: SetMountPath(value);
  160.                     break;
  161.  
  162.    case cfrepos:
  163.                    SetRepository(value);
  164.            break;
  165.  
  166.    case cfhomepat:  
  167.                   Debug1("Installing %s as home pattern\n",value);
  168.                   AppendItem(&VHOMEPATLIST,value,CLASSBUFF);
  169.                   break;
  170.  
  171.    case cfextension:
  172.                   AppendItem(&EXTENSIONLIST,value,CLASSBUFF);
  173.                   break;
  174.  
  175.    case cfsuspicious:
  176.                   AppendItem(&SUSPICIOUSLIST,value,CLASSBUFF);
  177.           break;
  178.           
  179.    case cftimezone:
  180.                    if (!IsDefinedClass(CLASSBUFF))
  181.                       {
  182.               break;
  183.               }
  184.  
  185.                     AppendItem(&VTIMEZONE,value,NULL);
  186.                     break;
  187.  
  188.    case cfssize: 
  189.                   sscanf(value,"%d",&number);
  190.                   if (number >= 0)
  191.                      {
  192.                      SENSIBLEFSSIZE = number;
  193.                      }
  194.                   else
  195.                      {
  196.                      yyerror("Silly value for sensiblesize (must be positive integer)");
  197.                      }
  198.                   break;
  199.  
  200.    case cfscount:
  201.                   sscanf(value,"%d",&number);
  202.                   if (number > 0)
  203.                      {
  204.                      SENSIBLEFILECOUNT = number;
  205.                      }
  206.                   else
  207.                      {
  208.                      yyerror("Silly value for sensiblecount (must be positive integer)");
  209.                      }
  210.  
  211.                   break;
  212.  
  213.    case cfeditsize:
  214.                   sscanf(value,"%d",&number);
  215.  
  216.                   if (number >= 0)
  217.                      {
  218.                      EDITFILESIZE = number;
  219.                      }
  220.                   else
  221.                      {
  222.                      yyerror("Silly value for editfilesize (must be positive integer)");
  223.                      }
  224.  
  225.                   break;
  226.  
  227.  
  228.    case cfifelapsed:
  229.                   sscanf(value,"%d",&number);
  230.  
  231.                   if (number >= 0)
  232.                      {
  233.                      VDEFAULTIFELAPSED = VIFELAPSED = number;
  234.                      }
  235.                   else
  236.                      {
  237.                      yyerror("Silly value for IfElapsed");
  238.                      }
  239.  
  240.                   break;
  241.           
  242.    case cfexpireafter:
  243.                   sscanf(value,"%d",&number);
  244.  
  245.                   if (number > 0)
  246.                      {
  247.                      VDEFAULTEXPIREAFTER = VEXPIREAFTER = number;
  248.                      }
  249.                   else
  250.                      {
  251.                      yyerror("Silly value for ExpireAfter");
  252.                      }
  253.  
  254.                   break;
  255.           
  256.  
  257.    case cfactseq:
  258.                   AppendToActionSequence(value);
  259.                   break;
  260.  
  261.    case cfaccess:
  262.                   AppendToAccessList(value);
  263.                   break;
  264.  
  265.    case cfnfstype:
  266.                   strcpy(VNFSTYPE,value); 
  267.                   break;
  268.  
  269.    case cfaddclass:
  270.                   AddCompoundClass(value);
  271.                   break;
  272.  
  273.    case cfinstallclass:
  274.                   AddInstallable(value);
  275.           break;
  276.           
  277.    case cfexcludecp:
  278.                   PrependItem(&VEXCLUDECOPY,value,CLASSBUFF);
  279.                   break;
  280.           
  281.    case cfexcludeln:
  282.                   PrependItem(&VEXCLUDELINK,value,CLASSBUFF);
  283.                   break;
  284.           
  285.    case cfcplinks:
  286.                   PrependItem(&VCOPYLINKS,value,CLASSBUFF);
  287.                   break;
  288.    case cflncopies:
  289.                   PrependItem(&VLINKCOPIES,value,CLASSBUFF);
  290.                   break;
  291.  
  292.    case cfrepchar:
  293.             if (strlen(value) > 1)
  294.             {
  295.             yyerror("reposchar can only be a single letter");
  296.             break;
  297.             }
  298.              if (value[0] == '/')
  299.             {
  300.             yyerror("illegal value for reposchar");
  301.             break;
  302.             }
  303.              REPOSCHAR = value[0];
  304.              break;
  305.  
  306.    case cflistsep:
  307.             if (strlen(value) > 1)
  308.                {
  309.                yyerror("listseparator can only be a single letter");
  310.                break;
  311.                }
  312.             if (value[0] == '/')
  313.                {
  314.                yyerror("illegal value for listseparator");
  315.                break;
  316.                }
  317.             LISTSEPARATOR = value[0];
  318.             break;
  319.             
  320.    case cfunderscore:
  321.                         if (strcmp(value,"on") == 0)
  322.                { char rename[maxvarsize];
  323.                UNDERSCORE_CLASSES=true;
  324.                Verbose("Resetting classes using underscores...\n");
  325.                while(DeleteItemContaining(&VHEAP,CLASSTEXT[VSYSTEMHARDCLASS]))
  326.                   {
  327.                   }
  328.  
  329.                sprintf(rename,"_%s",CLASSTEXT[VSYSTEMHARDCLASS]);
  330.                
  331.                            AddClassToHeap(rename);
  332.                break;
  333.                }
  334.  
  335.             if (strcmp(value,"off") == 0)
  336.                {
  337.                UNDERSCORE_CLASSES=false;
  338.                break;
  339.                }
  340.             
  341.                         yyerror("illegal value for underscoreclasses");
  342.             break;
  343.  
  344.    case cfifname:    if (strlen(value)>15)
  345.                         {
  346.                      yyerror("Silly interface name, (should be something link eth0)");
  347.                     }
  348.  
  349.                      strcpy(VIFNAMEOVERRIDE,value);
  350.              VIFDEV[VSYSTEMHARDCLASS] = VIFNAMEOVERRIDE; /* override */
  351.              Debug("Overriding interface with %s\n",VIFDEV[VSYSTEMHARDCLASS]);
  352.              break;
  353.  
  354.    case cfdefcopy: if (strcmp(value,"ctime") == 0)
  355.                       {
  356.               DEFAULTCOPYTYPE = 't';
  357.               return;
  358.               }
  359.                    else if (strcmp(value,"mtime") == 0)
  360.               {
  361.               DEFAULTCOPYTYPE = 'm';
  362.               return;
  363.               }
  364.                    else if (strcmp(value,"checksum")==0 || strcmp(value,"sum") == 0)
  365.               {
  366.               DEFAULTCOPYTYPE = 'c';
  367.               return;
  368.               }
  369.                    else if (strcmp(value,"byte")==0 || strcmp(value,"binary") == 0)
  370.               {
  371.               DEFAULTCOPYTYPE = 'b';
  372.               return;
  373.               }
  374.                    yyerror("Illegal default copy type");
  375.            break;
  376.  
  377.    default:       AddMacroValue(CURRENTITEM,value);
  378.                   break;
  379.    }
  380. }
  381.  
  382. /*******************************************************************/
  383.  
  384. HandleEdit(file,edit,string)      /* child routines in edittools.c */
  385.  
  386. char *file, *edit, *string;
  387.  
  388. {
  389. if (string == NULL)
  390.    {
  391.    Debug1("Handling Edit of %s, action [%s] with no data\n",file,edit);
  392.    }
  393. else
  394.    {
  395.    Debug1("Handling Edit of %s, action [%s] with data <%s>\n",file,edit,string);
  396.    }
  397.  
  398. if (EditFileExists(file))
  399.    {
  400.    AddEditAction(file,edit,string);
  401.    }
  402. else
  403.    {
  404.    InstallEditFile(file,edit,string);
  405.    }
  406. }
  407.  
  408. /********************************************************************/
  409.  
  410. HandleOptionalFileAttribute(item)
  411.  
  412. char *item;
  413.  
  414. { char value[maxvarsize];
  415.  
  416. VBUFF[0] = value[0] = '\0';
  417.  
  418. ExpandVarstring(item,VBUFF,NULL);
  419.  
  420. sscanf(VBUFF,"%*[^=]=%s",value);
  421.  
  422. if (value[0] == '\0')
  423.    {
  424.    yyerror("File attribute with no value");
  425.    }
  426.  
  427. Debug1("HandleOptionalFileAttribute(%s)\n",value);
  428.  
  429. switch(GetCommAttribute(item))
  430.    {
  431.    case cfrecurse: HandleRecurse(value);
  432.                    break;
  433.    case cfmode:    ParseModeString(value,&PLUSMASK,&MINUSMASK);
  434.                    break;
  435.    case cfflags:   ParseFlagString(value,&PLUSFLAG,&MINUSFLAG);
  436.                    break;           
  437.    case cfowner:   strcpy(VUIDNAME,value);
  438.                    break;
  439.    case cfgroup:   strcpy(VGIDNAME,value);
  440.                    break;
  441.    case cfaction:  FILEACTION = (enum fileactions) GetFileAction(value);
  442.                    break;
  443.    case cflinks:   HandleTravLinks(value);
  444.                    break;
  445.    case cfexclude: PrependItem(&VEXCLUDEPARSE,value,"any");
  446.                    break;
  447.    case cfinclude: PrependItem(&VINCLUDEPARSE,value,"any");
  448.                    break;
  449.    case cfignore:  PrependItem(&VIGNOREPARSE,value,"any");
  450.                    break;
  451.    case cfacl:     PrependItem(&VACLBUILD,value,"any");
  452.                    break;
  453.    case cfdefine:  HandleDefine(value);
  454.                    break;
  455.    case cfsetlog:  HandleSetLog(value);
  456.                    break;
  457.    case cfsetinform: HandleSetInform(value);
  458.                    break;
  459.  
  460.    case cfchksum:  HandleChecksum(value);
  461.                    break;
  462.    default:        yyerror("Illegal file attribute");
  463.    }
  464. }
  465.  
  466.  
  467. /*******************************************************************/
  468.  
  469. HandleOptionalImageAttribute(item)
  470.  
  471. char *item;
  472.  
  473. { char value[bufsize];
  474.  
  475. VBUFF[0] = value[0] = '\0';
  476.  
  477. ExpandVarstring(item,VBUFF,NULL);
  478.  
  479. sscanf(VBUFF,"%*[^=]=%s",value);
  480.  
  481. if (value[0] == '\0')
  482.    {
  483.    yyerror("Copy attribute with no value");
  484.    }
  485.  
  486. Debug1("HandleOptionalImageAttribute(%s)\n",value);
  487.  
  488. switch(GetCommAttribute(item))
  489.    {
  490.    case cfmode:    ParseModeString(value,&PLUSMASK,&MINUSMASK);
  491.                    break;
  492.    case cfflags:   ParseFlagString(value,&PLUSFLAG,&MINUSFLAG);
  493.                    break;
  494.    case cfowner:   strcpy(VUIDNAME,value);
  495.                    break;
  496.    case cfgroup:   strcpy(VGIDNAME,value);
  497.                    break;
  498.    case cfdest:    strcpy(DESTINATION,value);
  499.                    break;
  500.    case cfaction:  strcpy(IMAGEACTION,value);
  501.                    break;
  502.    case cfforce:   HandleForceCopy(value);
  503.                    break;
  504.    case cfbackup:  HandleCopyBackup(value);
  505.                    break;
  506.    case cfrecurse: HandleRecurse(value);
  507.                    break;
  508.    case cftype:    HandleCopyType(value);
  509.                    break;
  510.    case cfexclude: PrependItem(&VEXCLUDEPARSE,value,"any");
  511.                    break;
  512.    case cfsymlink: PrependItem(&VCPLNPARSE,value,"any");
  513.                    break;
  514.    case cfinclude: PrependItem(&VINCLUDEPARSE,value,"any");
  515.                    break;
  516.    case cfignore:  PrependItem(&VIGNOREPARSE,value,"any");
  517.                    break;
  518.    case cflntype:  HandleLinkType(value);
  519.                    break;
  520.    case cfserver:  HandleServer(value);
  521.                    break;
  522.    case cfsecure:  HandleSetSecure(value);
  523.                    break;
  524.    case cfdefine:  HandleDefine(value);
  525.                    break;
  526.    case cfsize:    HandleCopySize(value);
  527.                    break;
  528.    case cfacl:     PrependItem(&VACLBUILD,value,"any");
  529.                    break;
  530.    case cfpurge:   HandlePurge(value);
  531.                    break;
  532.    case cfsetlog:  HandleSetLog(value);
  533.                    break;
  534.    case cfsetinform: HandleSetInform(value);
  535.                    break;
  536.    case cfstealth: HandleStealth(value);
  537.                    break;
  538.  
  539.    default:        yyerror("Illegal copy attribute");
  540.    }
  541. }
  542.  
  543. /******************************************************************/
  544.  
  545. HandleOptionalRequired(item)
  546.  
  547. char *item;
  548.  
  549. { char value[maxvarsize];
  550.  
  551. VBUFF[0] = value[0] = '\0';
  552.  
  553. ExpandVarstring(item,VBUFF,NULL);
  554.  
  555. sscanf(VBUFF,"%*[^=]=%s",value);
  556.  
  557. if (value[0] == '\0')
  558.    {
  559.    yyerror("Required/disk attribute with no value");
  560.    }
  561.  
  562. Debug1("HandleOptionalRequiredAttribute(%s)\n",value);
  563.  
  564. switch(GetCommAttribute(item))
  565.    {
  566.    case cffree:    HandleRequiredSize(value);
  567.                    break;
  568.    case cfdefine:  HandleDefine(value);
  569.                    break;
  570.    case cfsetlog:  HandleSetLog(value);
  571.                    break;
  572.    case cfsetinform: HandleSetInform(value);
  573.                    break;
  574.  
  575.    default:        yyerror("Illegal disk/required attribute");
  576.    }
  577.  
  578. }
  579.  
  580. /******************************************************************/
  581.  
  582. HandleOptionalInterface(item)
  583.  
  584. char *item;
  585.  
  586. { char value[maxvarsize];
  587.  
  588. VBUFF[0] = value[0] = '\0';
  589.  
  590. ExpandVarstring(item,VBUFF,NULL);
  591.  
  592. sscanf(VBUFF,"%*[^=]=%s",value);
  593.  
  594. if (value[0] == '\0')
  595.    {
  596.    yyerror("intefaces attribute with no value");
  597.    }
  598.  
  599. Debug1("HandleOptionalRequiredAttribute(%s)\n",value);
  600.  
  601. switch(GetCommAttribute(item))
  602.    {
  603.    case cfsetnetmask:   HandleNetmask(value);
  604.                         break;
  605.    case cfsetbroadcast: HandleBroadcast(value);
  606.                         break;
  607.  
  608.    default:        yyerror("Illegal interfaces attribute");
  609.    }
  610.  
  611. }
  612.  
  613.  
  614. /******************************************************************/
  615.  
  616. HandleOptionalUnMountAttribute(item)
  617.  
  618. char *item;
  619.  
  620. { char value[maxvarsize];
  621.  
  622. VBUFF[0] = value[0] = '\0';
  623.  
  624. ExpandVarstring(item,VBUFF,NULL);
  625.  
  626. sscanf(VBUFF,"%*[^=]=%s",value);
  627.  
  628. if (value[0] == '\0')
  629.    {
  630.    yyerror("Unmount attribute with no value");
  631.    }
  632.  
  633. Debug1("HandleOptionalUnMountsItem(%s)\n",value);
  634.  
  635. switch(GetCommAttribute(item))
  636.    {
  637.    case cfdeldir: if (strcmp(value,"true") == 0 || strcmp(value,"yes") == 0)
  638.                      {
  639.              DELETEDIR = 't';
  640.              break;
  641.              }
  642.    
  643.                   if (strcmp(value,"false") == 0 || strcmp(value,"no") == 0)
  644.                      {
  645.              DELETEDIR = 'f';
  646.              break;
  647.              }
  648.  
  649.    case cfdelfstab: if (strcmp(value,"true") == 0 || strcmp(value,"yes") == 0)
  650.                        {
  651.                DELETEFSTAB = 't';
  652.                break;
  653.                }
  654.    
  655.                     if (strcmp(value,"false") == 0 || strcmp(value,"no") == 0)
  656.                        {
  657.                DELETEDIR = 'f';
  658.                break;
  659.                }   
  660.             
  661.    case cfforce:    if (strcmp(value,"true") == 0 || strcmp(value,"yes") == 0)
  662.                        {
  663.                FORCE = 't';
  664.                break;
  665.                }
  666.    
  667.                     if (strcmp(value,"false") == 0 || strcmp(value,"no") == 0)
  668.                        {
  669.                FORCE = 'f';
  670.                break;
  671.                }
  672.  
  673.    default:         yyerror("Illegal unmount attribute (rw/ro)");
  674.    }
  675.  
  676. }
  677.  
  678. /******************************************************************/
  679.  
  680. HandleOptionalMiscMountsAttribute(item)
  681.  
  682. char *item;
  683.  
  684. { char value[maxvarsize];
  685.  
  686. VBUFF[0] = value[0] = '\0';
  687.  
  688. ExpandVarstring(item,VBUFF,NULL);
  689.  
  690. sscanf(VBUFF,"%*[^=]=%s",value);
  691.  
  692. if (value[0] == '\0')
  693.    {
  694.    yyerror("Miscmounts attribute with no value");
  695.    }
  696.  
  697. Debug1("HandleOptionalMiscMOuntsItem(%s)\n",value);
  698.  
  699. switch(GetCommAttribute(item))
  700.    {
  701.    case cfmode:    if (strcmp(value,"rw") == 0)
  702.                       {
  703.               MOUNTMODE='w';
  704.               break;
  705.                       }
  706.    
  707.                    if (strcmp(value,"ro") == 0)
  708.                       {
  709.               MOUNTMODE='o';
  710.               break;
  711.                       }
  712.    
  713.    default:        yyerror("Illegal miscmounts attribute (rw/ro)");
  714.    }
  715.  
  716. }
  717.  
  718. /******************************************************************/
  719.  
  720. HandleOptionalTidyAttribute(item)
  721.  
  722. char *item;
  723.  
  724. { char value[maxvarsize];
  725.  
  726. VBUFF[0] = value[0] = '\0';
  727.  
  728. ExpandVarstring(item,VBUFF,NULL);
  729.  
  730. sscanf(VBUFF,"%*[^=]=%s",value);
  731.  
  732. if (value[0] == '\0')
  733.    {
  734.    yyerror("Tidy attribute with no value");
  735.    }
  736.  
  737. Debug1("HandleOptionalTidyAttribute(%s)\n",value);
  738.  
  739. switch(GetCommAttribute(item))
  740.    {
  741.    case cfrecurse: HandleRecurse(value);
  742.                    break;
  743.  
  744.    case cfpattern: strcpy(CURRENTITEM,value);
  745.                    if (*value == '/')
  746.               {
  747.               yyerror("search pattern begins with / must be a relative name");
  748.               }
  749.                    break;
  750.  
  751.    case cfage:     HandleAge(value);
  752.                    break;
  753.  
  754.    case cflinks:   HandleTravLinks(value);
  755.                    break;
  756.  
  757.    case cfsize:    HandleTidySize(value);
  758.                    break;
  759.  
  760.    case cftype:    HandleTidyType(value);
  761.                    break;
  762.  
  763.    case cfdirlinks:
  764.                    HandleTidyLinkDirs(value);
  765.            break;
  766.  
  767.    case cfrmdirs:  HandleTidyRmdirs(value);
  768.                    break;
  769.  
  770.    case cfdefine:  HandleDefine(value);
  771.                    break;
  772.    case cfsetlog:  HandleSetLog(value);
  773.                    break;
  774.    case cfsetinform: HandleSetInform(value);
  775.                    break;
  776.  
  777.    default:        yyerror("Illegal tidy attribute");
  778.    }
  779. }
  780.  
  781. /******************************************************************/
  782.  
  783. HandleOptionalDirAttribute(item)
  784.  
  785. char *item;
  786.  
  787. { char value[maxvarsize];
  788.  
  789. VBUFF[0] = value[0] = '\0';
  790.  
  791. ExpandVarstring(item,VBUFF,NULL);
  792.  
  793. sscanf(item,"%*[^=]=%s",value);
  794.  
  795. if (value[0] == '\0')
  796.    {
  797.    yyerror("Directory attribute with no value");
  798.    }
  799.  
  800. Debug1("HandleOptionalDirAttribute(%s)\n",value);
  801.  
  802. switch(GetCommAttribute(item))
  803.    {
  804.    case cfmode:    ParseModeString(value,&PLUSMASK,&MINUSMASK);
  805.                    break;
  806.    case cfflags:   ParseFlagString(value,&PLUSFLAG,&MINUSFLAG);
  807.                    break;
  808.    case cfowner:   strcpy(VUIDNAME,value);
  809.                    break;
  810.    case cfgroup:   strcpy(VGIDNAME,value);
  811.                    break;
  812.    case cfdefine:  HandleDefine(value);
  813.                    break;
  814.    case cfsetlog:  HandleSetLog(value);
  815.                    break;
  816.    case cfsetinform: HandleSetInform(value);
  817.                    break;
  818.  
  819.    default:        yyerror("Illegal directory attribute");
  820.    }
  821. }
  822.  
  823.  
  824. /*******************************************************************/
  825.  
  826. HandleOptionalDisableAttribute(item)
  827.  
  828. char *item;
  829.  
  830. { char value[maxvarsize];
  831.  
  832. VBUFF[0] = value[0] = '\0';
  833.  
  834. ExpandVarstring(item,VBUFF,NULL);
  835.  
  836. sscanf(VBUFF,"%*[^=]=%s",value);
  837.  
  838. if (value[0] == '\0')
  839.    {
  840.    yyerror("Disable attribute with no value");
  841.    }
  842.  
  843. Debug1("HandleOptionalDisableAttribute(%s)\n",value);
  844.  
  845. switch(GetCommAttribute(item))
  846.    {
  847.    case cftype:    HandleDisableFileType(value);
  848.                    break;
  849.  
  850.    case cfrotate:  HandleDisableRotate(value);
  851.                    break;
  852.            
  853.    case cfsize:    HandleDisableSize(value);
  854.                    break;
  855.    case cfdefine:  HandleDefine(value);
  856.                    break;
  857.    case cfsetlog:  HandleSetLog(value);
  858.                    break;
  859.    case cfsetinform: HandleSetInform(value);
  860.                    break;
  861.  
  862.    default:        yyerror("Illegal disable attribute");
  863.    }
  864. }
  865.  
  866.  
  867. /*******************************************************************/
  868.  
  869. HandleOptionalLinkAttribute(item)
  870.  
  871. char *item;
  872.  
  873. { char value[maxvarsize];
  874.  
  875. VBUFF[0] = value[0] = '\0';
  876.  
  877. ExpandVarstring(item,VBUFF,NULL);
  878.  
  879. sscanf(VBUFF,"%*[^=]=%s",value);
  880.  
  881. if (value[0] == '\0')
  882.    {
  883.    yyerror("Link attribute with no value");
  884.    }
  885.  
  886. Debug1("HandleOptionalLinkAttribute(%s)\n",value);
  887.  
  888. switch(GetCommAttribute(item))
  889.    {
  890.    case cfaction:  HandleLinkAction(value);
  891.                    break;
  892.    case cftype:    HandleLinkType(value);
  893.                    break;
  894.    case cfexclude: PrependItem(&VEXCLUDEPARSE,value,"any");
  895.                    break;
  896.    case cfinclude: PrependItem(&VINCLUDEPARSE,value,"any");
  897.                    break;
  898.    case cfignore:  PrependItem(&VIGNOREPARSE,value,"any");
  899.                    break;
  900.    case cfcopy:    PrependItem(&VCPLNPARSE,value,"any");
  901.                    break;
  902.    case cfrecurse: HandleRecurse(value);
  903.                    break;
  904.    case cfcptype:  HandleCopyType(value);
  905.                    break;
  906.    case cfnofile:  HandleDeadLinks(value);
  907.                    break;
  908.    case cfdefine:  HandleDefine(value);
  909.                    break;
  910.    case cfsetlog:  HandleSetLog(value);
  911.                    break;
  912.    case cfsetinform: HandleSetInform(value);
  913.                    break;
  914.  
  915.    default:        yyerror("Illegal link attribute");
  916.    }
  917. }
  918.  
  919. /*******************************************************************/
  920.  
  921. HandleOptionalProcessAttribute(item)
  922.  
  923. char *item;
  924.  
  925. { char value[maxvarsize];
  926.  
  927. if (HAVE_RESTART)     /* wrote `restart' without following by ".." */
  928.    {
  929.    yyerror("Missing restart command (quoted string expected) or bad SetOptionString placement");
  930.    }
  931.  
  932. VBUFF[0] = value[0] = '\0';
  933.  
  934. ExpandVarstring(item,VBUFF,NULL);
  935.  
  936. sscanf(VBUFF,"%*[^=]=%s",value);
  937.  
  938. if (value[0] == '\0')
  939.    {
  940.    yyerror("Process attribute with no value");
  941.    }
  942.  
  943. Debug1("HandleOptionalProcessAttribute(%s)\n",value);
  944.  
  945. switch(GetCommAttribute(item))
  946.    {
  947.    case cfaction:  if (strcmp(value,"signal") == 0 || strcmp(value,"do") == 0)
  948.                       {
  949.               PROACTION = 's';
  950.                       }
  951.                    else if (strcmp(value,"warn") == 0)
  952.               {
  953.               PROACTION = 'w';
  954.               }
  955.                    else
  956.               {
  957.               yyerror("Unknown action for processes");
  958.               }
  959.                    break;
  960.    case cfmatches: HandleProcessMatches(value);
  961.                    break;
  962.    case cfsignal:  HandleProcessSignal(value);
  963.                    break;
  964.    case cfdefine:  HandleDefine(value);
  965.                    break;
  966.    case cfuseshell:HandleUseShell(value);
  967.                    break;
  968.    case cfsetlog:  HandleSetLog(value);
  969.                    break;
  970.    case cfsetinform: HandleSetInform(value);
  971.                    break;
  972.    case cfexclude: PrependItem(&VEXCLUDEPARSE,value,"any");
  973.                    break;
  974.    case cfinclude: PrependItem(&VINCLUDEPARSE,value,"any");
  975.                    break;
  976.            
  977.    default:        yyerror("Illegal process attribute");
  978.    }
  979. }
  980.  
  981. /*******************************************************************/
  982.  
  983. HandleOptionalScriptAttribute(item)
  984.  
  985. char *item;
  986.  
  987. { char value[maxvarsize];
  988.  
  989. VBUFF[0] = value[0] = '\0';
  990.  
  991. ExpandVarstring(item,VBUFF,NULL);
  992.  
  993. sscanf(VBUFF,"%*[^=]=%s",value);
  994.  
  995. if (value[0] == '\0')
  996.    {
  997.    yyerror("Shellcommand attribute with no value");
  998.    }
  999.  
  1000. Debug1("HandleOptionalLinkAttribute(%s)\n",value);
  1001.  
  1002. switch(GetCommAttribute(item))
  1003.    {
  1004.    case cftimeout:   HandleTimeOut(value);
  1005.                      break;
  1006.    case cfuseshell:  HandleUseShell(value);
  1007.                      break;
  1008.    case cfsetlog:    HandleSetLog(value);
  1009.                      break;
  1010.    case cfsetinform: HandleSetInform(value);
  1011.                      break;
  1012.    case cfowner:     strcpy(VUIDNAME,value);
  1013.              break;
  1014.    case cfgroup:     strcpy(VGIDNAME,value);
  1015.                      break;
  1016.    case cfdefine:    HandleDefine(value);
  1017.                      break;
  1018.  
  1019.    default:         yyerror("Illegal shellcommand attribute");
  1020.    }
  1021.  
  1022. }
  1023.  
  1024. /*******************************************************************/
  1025.  
  1026. HandleFileItem(item)
  1027.  
  1028. char *item;
  1029.  
  1030. { char err[100];
  1031.  
  1032. if (strcmp(item,"home") == 0)
  1033.    {
  1034.    ACTIONPENDING=true;
  1035.    strcpy(CURRENTPATH,"home");
  1036.    return;
  1037.    }
  1038.  
  1039. sprintf(err,"Unknown attribute %s",item);
  1040. yyerror(err);
  1041. }
  1042.  
  1043.  
  1044. /*******************************************************************/
  1045.  
  1046. InstallBroadcastItem(item)
  1047.  
  1048. char *item;
  1049.  
  1050. {
  1051. Debug1("Install broadcast mode (%s)\n",item);
  1052.  
  1053. if ( ! IsInstallable(CLASSBUFF))
  1054.    {
  1055.    Debug1("Not installing %s, no match\n",item);
  1056.    return;
  1057.    }
  1058.  
  1059. if (VBROADCAST[0] != '\0')
  1060.    {
  1061.    yyerror("Multiple declaration of variable broadcast");
  1062.    FatalError("Redefinition of basic system variable");
  1063.    }
  1064.  
  1065. if (strcmp("ones",item) == 0)
  1066.    {
  1067.    strcpy(VBROADCAST,"one");
  1068.    return;
  1069.    }
  1070.  
  1071. if (strcmp("zeroes",item) == 0)
  1072.    {
  1073.    strcpy(VBROADCAST,"zero");
  1074.    return;
  1075.    }
  1076.  
  1077. if (strcmp("zeros",item) == 0)
  1078.    {
  1079.    strcpy(VBROADCAST,"zero");
  1080.    return;
  1081.    }
  1082.  
  1083. yyerror ("Unknown broadcast mode (should be ones, zeros or zeroes)");
  1084. FatalError("Unknown broadcast mode");
  1085. }
  1086.  
  1087. /*******************************************************************/
  1088.  
  1089. InstallDefaultRouteItem(item)
  1090.  
  1091. char *item;
  1092.  
  1093. { struct hostent *hp;
  1094.   struct in_addr inaddr;
  1095.  
  1096. Debug1("Install defaultroute mode (%s)\n",item);
  1097.  
  1098. if (!IsDefinedClass(CLASSBUFF))
  1099.    {
  1100.    Debug1("Not installing %s, no match\n",item);
  1101.    return;
  1102.    }
  1103.  
  1104. if (VDEFAULTROUTE[0] != '\0')
  1105.    {
  1106.    yyerror("Multiple declaration of variable defaultroute");
  1107.    FatalError("Redefinition of basic system variable");
  1108.    }
  1109.  
  1110. ExpandVarstring(item,VBUFF,NULL);
  1111.  
  1112.  if (inet_addr(VBUFF) == -1)
  1113.    {
  1114.    if ((hp = gethostbyname(VBUFF)) == NULL)
  1115.       {
  1116.       sprintf(OUTPUT,"Bad address/host (%s) in default route\n",VBUFF);
  1117.       CfLog(cferror,OUTPUT,"gethostbyname");
  1118.       yyerror ("Bad specification of default packet route: hostname or decimal IP address");
  1119.       }
  1120.    else
  1121.       {
  1122.       bcopy(hp->h_addr,&inaddr, hp->h_length);
  1123.       strcpy(VDEFAULTROUTE,inet_ntoa(inaddr));
  1124.       }
  1125.    }
  1126. else
  1127.    {
  1128.    strcpy(VDEFAULTROUTE,VBUFF);
  1129.    }
  1130. }
  1131.  
  1132. /*******************************************************************/
  1133.  
  1134. HandleGroupItem(item,type)
  1135.  
  1136. char *item;
  1137. enum itemtypes type;
  1138.  
  1139. { char *machine, *user, *domain;
  1140.  
  1141. Debug1("Handling item (%s) in group (%s), type=%d\n",item,GROUPBUFF,type);
  1142.  
  1143. switch (type)
  1144.    {
  1145.    case simple:    if (strcmp(item,VDEFAULTBINSERVER.name) == 0)
  1146.                       {
  1147.                       AddClassToHeap(GROUPBUFF);
  1148.                       break;
  1149.                       }
  1150.  
  1151.                    if (strcmp(item,VFQNAME) == 0)
  1152.                       {
  1153.                       AddClassToHeap(GROUPBUFF);
  1154.                       break;
  1155.                       }
  1156.  
  1157.                    if (IsItemIn(VHEAP,item))  /* group reference */
  1158.                       {
  1159.                       AddClassToHeap(GROUPBUFF);
  1160.                       break;
  1161.                       }
  1162.  
  1163.                    break;
  1164.  
  1165.    case netgroup:  setnetgrent(item);
  1166.  
  1167.                    while (getnetgrent(&machine,&user,&domain))
  1168.                       {
  1169.                       if (strcmp(machine,VDEFAULTBINSERVER.name) == 0)
  1170.                          {
  1171.                          Debug1("Matched %s in netgroup %s\n",machine,item);
  1172.                          AddClassToHeap(GROUPBUFF);
  1173.                          break;
  1174.                          }
  1175.  
  1176.               if (strcmp(machine,VFQNAME) == 0)
  1177.                          {
  1178.                          Debug1("Matched %s in netgroup %s\n",machine,item);
  1179.                          AddClassToHeap(GROUPBUFF);
  1180.                          break;
  1181.                          }
  1182.                       }
  1183.                    
  1184.                    endnetgrent();
  1185.                    break;
  1186.  
  1187.  
  1188.    case groupdeletion: 
  1189.  
  1190.                    setnetgrent(item);
  1191.  
  1192.                    while (getnetgrent(&machine,&user,&domain))
  1193.                       {
  1194.                       if (strcmp(machine,VDEFAULTBINSERVER.name) == 0)
  1195.                          {
  1196.                          Debug1("Matched delete item %s in netgroup %s\n",machine,item);
  1197.                          DeleteItemStarting(&VHEAP,GROUPBUFF);
  1198.                          break;
  1199.                          }
  1200.               
  1201.                       if (strcmp(machine,VFQNAME) == 0)
  1202.                          {
  1203.                          Debug1("Matched delete item %s in netgroup %s\n",machine,item);
  1204.                          DeleteItemStarting(&VHEAP,GROUPBUFF);
  1205.                          break;
  1206.                          }
  1207.               
  1208.                       }
  1209.                    
  1210.                    endnetgrent();
  1211.                    break;
  1212.  
  1213.    case classscript:
  1214.  
  1215.                    VBUFF[0] = '\0';
  1216.                    ExpandVarstring (item+1,VBUFF,NULL);
  1217.                    if (VBUFF[0] != '/')
  1218.                       {
  1219.                       yyerror("Quoted scripts must begin with / for absolute path");
  1220.                       break;
  1221.                       }
  1222.  
  1223.                    if (ShellCommandReturnsZero(VBUFF))
  1224.                       {
  1225.                       AddClassToHeap(GROUPBUFF);
  1226.                       }
  1227.  
  1228.                    break;
  1229.  
  1230.    case deletion:  if (IsDefinedClass(item))
  1231.                       {
  1232.                       DeleteItemStarting(&VHEAP,GROUPBUFF);
  1233.                       }
  1234.                    break;
  1235.  
  1236.    default:        yyerror("Software error");
  1237.                    FatalError("Unknown item type");
  1238.    }
  1239. }
  1240.  
  1241. /*******************************************************************/
  1242.  
  1243. HandleHomePattern(pattern)
  1244.  
  1245. char *pattern;
  1246.  
  1247. {
  1248. VBUFF[0]='\0';
  1249. ExpandVarstring(pattern,VBUFF,"");
  1250. AppendItem(&VHOMEPATLIST,VBUFF,CLASSBUFF);
  1251. }
  1252.  
  1253. /*******************************************************************/
  1254.  
  1255. AppendNameServer(item)
  1256.  
  1257. char *item;
  1258.  
  1259. Debug1("Installing item (%s) in the nameserver list\n",item);
  1260.  
  1261. if ( ! IsInstallable(CLASSBUFF))
  1262.    {
  1263.    Debug1("Not installing %s, no match\n",item);
  1264.    return;
  1265.    }
  1266.  
  1267. AppendItem(&VRESOLVE,item,CLASSBUFF);
  1268. }
  1269.  
  1270. /*******************************************************************/
  1271.  
  1272. AppendImport(item)
  1273.  
  1274. char *item;
  1275.  
  1276. if ( ! IsInstallable(CLASSBUFF))
  1277.    {
  1278.    Debug1("Not installing %s, no match\n",item);
  1279.    return;
  1280.    }
  1281.  
  1282. if (strcmp(item,VCURRENTFILE) == 0)
  1283.    {
  1284.    yyerror("A file cannot import itself");
  1285.    FatalError("Infinite self-reference in class inheritance");
  1286.    }
  1287.  
  1288. Debug1(">>Installing item (%s) in the import list\n",item);
  1289.  
  1290. ExpandVarstring(item,VBUFF,"");
  1291.  
  1292. AppendItem(&VIMPORT,VBUFF,CLASSBUFF);
  1293. }
  1294.  
  1295.  
  1296. /*******************************************************************/
  1297.  
  1298. InstallHomeserverItem(item)
  1299.  
  1300. char *item;
  1301.  
  1302. {
  1303. if ( ! IsInstallable(CLASSBUFF))
  1304.    {
  1305.    Debug1("Not installing %s, no match\n",item);
  1306.    return;
  1307.    }
  1308.  
  1309. Debug1("Installing item (%s) in  list for homeservers (%s) in group (%s)\n",item,CLASSBUFF,GROUPBUFF);
  1310.  
  1311. AppendItem(&VHOMESERVERS,item,CLASSBUFF);
  1312. }
  1313.  
  1314. /*******************************************************************/
  1315.  
  1316. InstallBinserverItem(item)           /* Install if matches classes */
  1317.  
  1318. char *item;
  1319.  
  1320. {
  1321. if ( ! IsInstallable(CLASSBUFF))
  1322.    {
  1323.    Debug1("Not installing %s, no match\n",item);
  1324.    return;
  1325.    }
  1326.  
  1327. AppendItem(&VBINSERVERS,item,CLASSBUFF);
  1328. }
  1329.  
  1330. /*******************************************************************/
  1331.  
  1332. InstallMailserverPath(path)
  1333.  
  1334. char *path;
  1335.  
  1336. {
  1337. if ( ! IsInstallable(CLASSBUFF))
  1338.    {
  1339.    Debug1("Not installing %s, no match\n",path);
  1340.    return;
  1341.    }
  1342.  
  1343. if (VMAILSERVER[0] != '\0')
  1344.    {
  1345.    FatalError("Redefinition of mailserver");
  1346.    }
  1347.  
  1348. strcpy(VMAILSERVER,path);
  1349.  
  1350. Debug1("Installing mailserver (%s) for group (%s)",path,GROUPBUFF);
  1351. }
  1352.  
  1353. /*******************************************************************/
  1354.  
  1355. InstallLinkItem (from,to)
  1356.  
  1357. char *from, *to;
  1358.  
  1359. { struct Link *ptr;
  1360.   char buffer[bufsize], buffer2[bufsize];
  1361.   
  1362. Debug1("Storing Link: (From)%s->(To)%s\n",from,to);
  1363.  
  1364. if ( ! IsInstallable(CLASSBUFF))
  1365.    {
  1366.    InitializeAction();
  1367.    Debug1("Not installing link no match\n");
  1368.    return;
  1369.    }
  1370.  
  1371. bzero(VBUFF,bufsize);
  1372. ExpandVarstring(from,VBUFF,"");
  1373. if (strlen(VBUFF) > 1)
  1374.    {
  1375.    DeleteSlash(VBUFF);
  1376.    }
  1377.  
  1378. bzero(buffer,bufsize);
  1379. ExpandVarstring(to,buffer,"");
  1380.  
  1381. if (strlen(VBUFF) > 1)
  1382.    { 
  1383.    DeleteSlash(buffer);
  1384.    }
  1385.  
  1386. bzero(buffer2,bufsize);
  1387. ExpandVarstring(ALLCLASSBUFFER,buffer2,""); 
  1388.  
  1389. if ((ptr = (struct Link *)malloc(sizeof(struct Link))) == NULL)
  1390.    {
  1391.    FatalError("Memory Allocation failed for InstallListItem() #1");
  1392.    }
  1393.  
  1394. if ((ptr->from = strdup(VBUFF)) == NULL)
  1395.    {
  1396.    FatalError("Memory Allocation failed for InstallListItem() #2");
  1397.    }
  1398.  
  1399. if ((ptr->to = strdup(buffer)) == NULL)
  1400.    {
  1401.    FatalError("Memory Allocation failed for InstallListItem() #3");
  1402.    }
  1403.  
  1404. if ((ptr->classes = strdup(CLASSBUFF)) == NULL)
  1405.    {
  1406.    FatalError("Memory Allocation failed for InstallListItem() #4");
  1407.    }
  1408.  
  1409. if ((ptr->defines = strdup(buffer2)) == NULL)
  1410.    {
  1411.    FatalError("Memory Allocation failed for InstallListItem() #4a");
  1412.    }
  1413.  
  1414. AddInstallable(ptr->defines);
  1415.  
  1416. if (VLINKTOP == NULL)                 /* First element in the list */
  1417.    {
  1418.    VLINK = ptr;
  1419.    }
  1420. else
  1421.    {
  1422.    VLINKTOP->next = ptr;
  1423.    }
  1424.  
  1425. if (strlen(ptr->from) > 1)
  1426.    {
  1427.    DeleteSlash(ptr->from);
  1428.    }
  1429.  
  1430. if (strlen(ptr->to) > 1)
  1431.    {
  1432.    DeleteSlash(ptr->to);
  1433.    }
  1434.  
  1435. ptr->force = FORCELINK;
  1436. ptr->silent = LINKSILENT;
  1437. ptr->type = LINKTYPE;
  1438. ptr->copytype = COPYTYPE;
  1439. ptr->next = NULL;
  1440. ptr->copy = VCPLNPARSE;
  1441. ptr->exclusions = VEXCLUDEPARSE;
  1442. ptr->inclusions = VINCLUDEPARSE;
  1443. ptr->ignores = VIGNOREPARSE;
  1444. ptr->recurse = VRECURSE;
  1445. ptr->nofile = DEADLINKS;
  1446. ptr->log = LOGP;
  1447. ptr->inform = INFORMP;
  1448.  
  1449.  
  1450. VLINKTOP = ptr;
  1451.  
  1452. if (ptr->recurse != 0)
  1453.    {
  1454.    yyerror("Recursion can only be used with +> multiple links");
  1455.    }
  1456.  
  1457. InitializeAction();
  1458. }
  1459.  
  1460. /*******************************************************************/
  1461.  
  1462. InstallLinkChildrenItem (from,to)
  1463.  
  1464. char *from, *to;
  1465.  
  1466. { struct Link *ptr;
  1467.   char *sp, buffer[bufsize];
  1468.   struct TwoDimList *tp = NULL;
  1469.  
  1470. Debug1("Storing Linkchildren item: %s -> %s\n",from,to);
  1471.  
  1472. if ( ! IsInstallable(CLASSBUFF))
  1473.    {
  1474.    InitializeAction();
  1475.    Debug1("Not installing linkchildren no match\n");
  1476.    return;
  1477.    }
  1478.  
  1479. VBUFF[0]='\0';                                /* Expand any variables */
  1480. ExpandVarstring(from,VBUFF,"");
  1481.  
  1482. bzero(buffer,bufsize);
  1483. ExpandVarstring(ALLCLASSBUFFER,buffer,""); 
  1484.  
  1485. Build2DListFromVarstring(&tp,to,'/');
  1486.     
  1487. Set2DList(tp);
  1488.  
  1489. for (sp = Get2DListEnt(tp); sp != NULL; sp = Get2DListEnt(tp))
  1490.    {
  1491.    if ((ptr = (struct Link *)malloc(sizeof(struct Link))) == NULL)
  1492.       {
  1493.       FatalError("Memory Allocation failed for InstallListChildrenItem() #1");
  1494.       }
  1495.  
  1496.    if ((ptr->from = strdup(VBUFF)) == NULL)
  1497.       {
  1498.       FatalError("Memory Allocation failed for InstallLinkchildrenItem() #2");
  1499.       }
  1500.  
  1501.    if ((ptr->to = strdup(sp)) == NULL)
  1502.       {
  1503.       FatalError("Memory Allocation failed for InstallLinkChildrenItem() #3");
  1504.       }
  1505.  
  1506.    if ((ptr->classes = strdup(CLASSBUFF)) == NULL)
  1507.       {
  1508.       FatalError("Memory Allocation failed for InstallLinkChildrenItem() #3");
  1509.       }
  1510.  
  1511. if ((ptr->defines = strdup(buffer)) == NULL)
  1512.    {
  1513.    FatalError("Memory Allocation failed for InstallListItem() #4a");
  1514.    }
  1515.  
  1516. AddInstallable(ptr->defines);
  1517.  
  1518.  if (VCHLINKTOP == NULL)                 /* First element in the list */
  1519.       {
  1520.       VCHLINK = ptr;
  1521.       }
  1522.    else
  1523.       {
  1524.       VCHLINKTOP->next = ptr;
  1525.       }
  1526.  
  1527.    ptr->force = FORCELINK;
  1528.    ptr->silent = LINKSILENT;
  1529.    ptr->type = LINKTYPE;
  1530.    ptr->next = NULL;
  1531.    ptr->copy = VCPLNPARSE;
  1532.    ptr->exclusions = VEXCLUDEPARSE;
  1533.    ptr->inclusions = VINCLUDEPARSE;
  1534.    ptr->ignores = VIGNOREPARSE;
  1535.    ptr->recurse = VRECURSE;
  1536.    ptr->log = LOGP;
  1537.    ptr->inform = INFORMP;
  1538.  
  1539.    VCHLINKTOP = ptr;
  1540.  
  1541.    if (ptr->recurse != 0 && strcmp(ptr->to,"linkchildren") == 0)
  1542.       {
  1543.       yyerror("Sorry don't know how to recurse with linkchildren keyword");
  1544.       }
  1545.    }
  1546.  
  1547. Delete2DList(tp);
  1548.  
  1549. InitializeAction();
  1550. }
  1551.  
  1552.  
  1553. /*******************************************************************/
  1554.  
  1555. InstallRequiredPath(path,defines,freespace)
  1556.  
  1557. char *path, *defines;
  1558. int freespace;
  1559.  
  1560. { struct Disk *ptr;
  1561.   char buffer[bufsize];
  1562.  
  1563. Debug1("Installing item (%s) in the required list\n",path);
  1564.  
  1565. if ( ! IsInstallable(CLASSBUFF))
  1566.    {
  1567.    InitializeAction();
  1568.    Debug1("Not installing %s, no match\n",path);
  1569.    return;
  1570.    }
  1571.  
  1572. VBUFF[0] = '\0';
  1573. ExpandVarstring(path,VBUFF,"");
  1574.  
  1575. buffer[0] = '\0';
  1576. ExpandVarstring(defines,buffer,"");
  1577.  
  1578.  
  1579. /* AppendItem(&VREQUIRED,VBUFF,CLASSBUFF);*/
  1580.  
  1581. if ((ptr = (struct Disk *)malloc(sizeof(struct Disk))) == NULL)
  1582.    {
  1583.    FatalError("Memory Allocation failed for InstallRequired() #1");
  1584.    }
  1585.  
  1586. if ((ptr->name = strdup(VBUFF)) == NULL)
  1587.    {
  1588.    FatalError("Memory Allocation failed for InstallRequired() #2");
  1589.    }
  1590.  
  1591. if ((ptr->classes = strdup(CLASSBUFF)) == NULL)
  1592.    {
  1593.    FatalError("Memory Allocation failed for InstallRequired() #2");
  1594.    }
  1595.  
  1596. if ((ptr->define = strdup(buffer)) == NULL)
  1597.    {
  1598.    FatalError("Memory Allocation failed for Installrequied() #2");
  1599.    }
  1600.  
  1601. if (VREQUIRED == NULL)                 /* First element in the list */
  1602.    {
  1603.    VREQUIRED = ptr;
  1604.    }
  1605. else
  1606.    {
  1607.    VREQUIREDTOP->next = ptr;
  1608.    }
  1609.  
  1610. AddInstallable(ptr->define);
  1611. ptr->freespace = freespace;
  1612. ptr->next = NULL;
  1613. ptr->log = LOGP;
  1614. ptr->inform = INFORMP;
  1615.  
  1616. VREQUIREDTOP = ptr;
  1617.  
  1618. InitializeAction();
  1619. }
  1620.  
  1621. /*******************************************************************/
  1622.  
  1623. AppendMountable(path)
  1624.  
  1625. char *path;
  1626.  
  1627. {
  1628. Debug1("Adding mountable %s to list\n",path);
  1629.  
  1630. AppendItem(&VMOUNTABLES,path,CLASSBUFF);
  1631. }
  1632.  
  1633. /*******************************************************************/
  1634.  
  1635. AppendUmount(path,deldir,delfstab,force)
  1636.  
  1637. char *path;
  1638. char deldir,delfstab,force;
  1639.  
  1640. { struct UnMount *ptr;
  1641.  
  1642. if ( ! IsInstallable(CLASSBUFF))
  1643.    {
  1644.    InitializeAction();
  1645.    Debug1("Not installing %s, no match\n",path);
  1646.    return;
  1647.    }
  1648.  
  1649. VBUFF[0] = '\0';
  1650. ExpandVarstring(path,VBUFF,"");
  1651.  
  1652.  if ((ptr = (struct UnMount *)malloc(sizeof(struct UnMount))) == NULL)
  1653.    {
  1654.    FatalError("Memory Allocation failed for AppendMiscMount #1");
  1655.    }
  1656.  
  1657. if ((ptr->name = strdup(VBUFF)) == NULL)
  1658.    {
  1659.    FatalError("Memory Allocation failed for InstallRequired() #2");
  1660.    }
  1661.  
  1662. if ((ptr->classes = strdup(CLASSBUFF)) == NULL)
  1663.    {
  1664.    FatalError("Memory Allocation failed for AppendMiscMount() #5");
  1665.    }
  1666.  
  1667. if (VUNMOUNTTOP == NULL)                 /* First element in the list */
  1668.    {
  1669.    VUNMOUNT = ptr;
  1670.    }
  1671. else
  1672.    {
  1673.    VUNMOUNTTOP->next = ptr;
  1674.    }
  1675.  
  1676. ptr->next = NULL;
  1677. ptr->deletedir = deldir;  /* t/f - true false */
  1678. ptr->deletefstab = delfstab;
  1679. ptr->force = force;
  1680. VUNMOUNTTOP = ptr;
  1681. }
  1682.  
  1683. /*******************************************************************/
  1684.  
  1685. AppendMiscMount(from,onto,perm)
  1686.  
  1687. char *from, *onto, *perm;
  1688.  
  1689. { struct MiscMount *ptr;
  1690.  
  1691. Debug1("Adding misc mountable %s %s (%s) to list\n",from,onto,perm);
  1692.  
  1693. if ( ! IsInstallable(CLASSBUFF))
  1694.    {
  1695.    Debug1("Not installing %s, no match\n",from);
  1696.    return;
  1697.    }
  1698.  
  1699. if ((ptr = (struct MiscMount *)malloc(sizeof(struct MiscMount))) == NULL)
  1700.    {
  1701.    FatalError("Memory Allocation failed for AppendMiscMount #1");
  1702.    }
  1703.  
  1704. ExpandVarstring(from,VBUFF,"");
  1705.  
  1706. if ((ptr->from = strdup(VBUFF)) == NULL)
  1707.    {
  1708.    FatalError("Memory Allocation failed for AppendMiscMount() #2");
  1709.    }
  1710.  
  1711. ExpandVarstring(onto,VBUFF,"");
  1712.  
  1713. if ((ptr->onto = strdup(onto)) == NULL)
  1714.    {
  1715.    FatalError("Memory Allocation failed for AppendMiscMount() #3");
  1716.    }
  1717.  
  1718. if ((ptr->options = strdup(perm)) == NULL)
  1719.    {
  1720.    FatalError("Memory Allocation failed for AppendMiscMount() #4");
  1721.    }
  1722.  
  1723. if ((ptr->classes = strdup(CLASSBUFF)) == NULL)
  1724.    {
  1725.    FatalError("Memory Allocation failed for AppendMiscMount() #5");
  1726.    }
  1727.  
  1728. if (VMISCMOUNTTOP == NULL)                 /* First element in the list */
  1729.    {
  1730.    VMISCMOUNT = ptr;
  1731.    }
  1732. else
  1733.    {
  1734.    VMISCMOUNTTOP->next = ptr;
  1735.    }
  1736.  
  1737. ptr->next = NULL;
  1738. VMISCMOUNTTOP = ptr;
  1739. }
  1740.  
  1741.  
  1742. /*******************************************************************/
  1743.  
  1744. AppendIgnore(path)
  1745.  
  1746. char *path;
  1747.  
  1748. { struct TwoDimList *tp = NULL;
  1749.   char *sp;
  1750.  
  1751. Debug1("Installing item (%s) in the ignore list\n",path);
  1752.  
  1753. if ( ! IsInstallable(CLASSBUFF))
  1754.    {
  1755.    Debug1("Not installing %s, no match\n",path);
  1756.    return;
  1757.    }
  1758.  
  1759. Build2DListFromVarstring(&tp,path,'/');
  1760.     
  1761. Set2DList(tp);
  1762.  
  1763. for (sp = Get2DListEnt(tp); sp != NULL; sp = Get2DListEnt(tp))
  1764.    {
  1765.    AppendItem(&VIGNORE,sp,CLASSBUFF);
  1766.    }
  1767.  
  1768. Delete2DList(tp);
  1769. }
  1770.  
  1771. /*******************************************************************/
  1772.  
  1773. InstallPending(action)
  1774.  
  1775. enum actions action;
  1776.  
  1777. {
  1778. if (ACTIONPENDING)
  1779.    {
  1780.    Debug1("\n   [BEGIN InstallPending %s\n",ACTIONTEXT[action]);
  1781.    }
  1782. else
  1783.    {
  1784.    Debug1("   (No actions pending in %s)\n",ACTIONTEXT[action]);
  1785.    return;
  1786.    }
  1787.  
  1788. switch (action)
  1789.    {
  1790.    case files:
  1791.                   InstallFileListItem(CURRENTPATH,PLUSMASK,MINUSMASK,FILEACTION,VUIDNAME,
  1792.                       VGIDNAME,VRECURSE,(char)PTRAVLINKS,ALLCLASSBUFFER,CHECKSUM);
  1793.                   break;
  1794.  
  1795.    case processes: InstallProcessItem(EXPR,RESTART,PROMATCHES,PROCOMP,
  1796.                       PROSIGNAL,PROACTION,CLASSBUFF,ALLCLASSBUFFER,USESHELL);
  1797.                    break;
  1798.    case image:
  1799.                   InstallImageItem(CURRENTPATH,PLUSMASK,MINUSMASK,DESTINATION,
  1800.                    IMAGEACTION,VUIDNAME,VGIDNAME,FORCECOPY,IMGSIZE,IMGCOMP,
  1801.                    IMAGEBACKUP,VRECURSE,COPYTYPE,LINKTYPE,CFSERVER,
  1802.                    ALLCLASSBUFFER,PURGE,STEALTH,SECURE);
  1803.                   break;
  1804.  
  1805.    case tidy:     if (VAGE >= 99999)
  1806.                      {
  1807.                      yyerror("Must specify an age for tidy actions");
  1808.                      return;
  1809.                      }
  1810.                   InstallTidyItem(CURRENTPATH,CURRENTITEM,VRECURSE,VAGE,(char)PTRAVLINKS,
  1811.                   TIDYSIZE,AGETYPE,LINKDIRS,TIDYDIRS,CLASSBUFF,ALLCLASSBUFFER);
  1812.                   break;
  1813.  
  1814.    case makepath: InstallMakePath(CURRENTPATH,PLUSMASK,MINUSMASK,VUIDNAME,VGIDNAME,ALLCLASSBUFFER);
  1815.                   break;
  1816.  
  1817.    case disable:  AppendDisable(CURRENTPATH,CURRENTITEM,ROTATE,DISCOMP,DISABLESIZE,ALLCLASSBUFFER);
  1818.                   break;
  1819.  
  1820.    case shellcommands:
  1821.                   AppendScript(CURRENTPATH,VTIMEOUT,USESHELL,VUIDNAME,VGIDNAME);
  1822.           break;
  1823.  
  1824.    case interfaces:
  1825.                   AppendInterface(VIFNAME,DESTINATION,CURRENTPATH);
  1826.           break;
  1827.  
  1828.    case required:
  1829.                   InstallRequiredPath(CURRENTPATH,ALLCLASSBUFFER,IMGSIZE);
  1830.                   break;
  1831.  
  1832.    case misc_mounts:
  1833.  
  1834.                   if ((strlen(MOUNTFROM) != 0) && (strlen(MOUNTONTO) != 0))
  1835.              {
  1836.              switch (MOUNTMODE)
  1837.             {
  1838.             case 'o': AppendMiscMount(MOUNTFROM,MOUNTONTO,"ro");
  1839.                 break;
  1840.             case 'w': AppendMiscMount(MOUNTFROM,MOUNTONTO,"rw");
  1841.                 break;
  1842.             default:  printf("Install pending, miscmount, shouldn't happen\n");
  1843.             }
  1844.              }
  1845.           
  1846.           InitializeAction();
  1847.           break;
  1848.  
  1849.    case unmounta:
  1850.                   AppendUmount(CURRENTPATH,DELETEDIR,DELETEFSTAB,FORCE);
  1851.           break;
  1852.            
  1853.    case links:
  1854.  
  1855.                   if (LINKTO[0] == '\0')
  1856.                      {
  1857.                      return;
  1858.                      }
  1859.  
  1860.                   if (ACTION_IS_LINKCHILDREN)
  1861.                      {
  1862.                      InstallLinkChildrenItem(LINKFROM,LINKTO);
  1863.                      ACTION_IS_LINKCHILDREN = false;
  1864.                      }
  1865.                   else if (ACTION_IS_LINK)
  1866.                      {
  1867.                      InstallLinkItem(LINKFROM,LINKTO);
  1868.                      ACTION_IS_LINK = false;
  1869.                      }
  1870.                   else
  1871.                      {
  1872.                      return;                                   /* Don't have whole command */
  1873.                      }
  1874.  
  1875.                   break;
  1876.    }
  1877.  
  1878. LINKFROM[0] = '\0';
  1879. LINKTO[0] = '\0';
  1880. ACTIONPENDING = false;
  1881. CURRENTITEM[0] = '\0';
  1882. CURRENTITEM[0] = '\0';
  1883. VRECURSE = 0;
  1884. VAGE=99999;
  1885. Debug1("   END InstallPending]\n\n");
  1886. }
  1887.  
  1888. /*******************************************************************/
  1889. /* Level 3                                                         */
  1890. /*******************************************************************/
  1891.  
  1892. EditFileExists(file)
  1893.  
  1894. char *file;
  1895.  
  1896. { struct Edit *ptr;
  1897.  
  1898. VBUFF[0]='\0';                         /* Expand any variables */
  1899. ExpandVarstring(file,VBUFF,"");
  1900.  
  1901. for (ptr=VEDITLIST; ptr != NULL; ptr=ptr->next)
  1902.    {
  1903.    if (strcmp(ptr->fname,VBUFF) == 0)
  1904.       {
  1905.       return true;
  1906.       }
  1907.    }
  1908. return false;
  1909. }
  1910.  
  1911. /********************************************************************/
  1912.  
  1913. GetExecOutput(command,buffer)
  1914.  
  1915. /* Buffer initially contains whole exec string */
  1916.  
  1917. char *command, *buffer;
  1918.  
  1919. { int offset = 0;
  1920.   char line[bufsize], *sp; 
  1921.   FILE *pp;
  1922.  
  1923. Debug1("GetExecOutput(%s,%s)\n",command,buffer);
  1924.   
  1925. if (DONTDO)
  1926.    {
  1927.    return;
  1928.    }
  1929.  
  1930. if ((pp = cfpopen(command,"r")) == NULL)
  1931.    {
  1932.    sprintf(OUTPUT,"Couldn't open pipe to command %s\n",command);
  1933.    CfLog(cfinform,OUTPUT,"pipe");
  1934.    return false;
  1935.    }
  1936.  
  1937. bzero(buffer,bufsize);
  1938.   
  1939. while (!feof(pp))
  1940.    {
  1941.    if (ferror(pp))  /* abortable */
  1942.       {
  1943.       fflush(pp);
  1944.       break;
  1945.       }
  1946.  
  1947.    ReadLine(line,bufsize,pp);
  1948.  
  1949.    if (ferror(pp))  /* abortable */
  1950.       {
  1951.       fflush(pp);
  1952.       break;
  1953.       }     
  1954.  
  1955.    for (sp = line; *sp != '\0'; sp++)
  1956.       {
  1957.       if (*sp == '\n')
  1958.      {
  1959.      *sp = ' ';
  1960.      }
  1961.       }
  1962.  
  1963.    if (strlen(line)+offset > bufsize-10)
  1964.       {
  1965.       sprintf(OUTPUT,"Buffer exceeded %d bytes in exec %s\n",maxvarsize,command);
  1966.       CfLog(cferror,OUTPUT,"");
  1967.       break;
  1968.       }
  1969.  
  1970.    sprintf(buffer+offset,"%s ",line);
  1971.    offset += strlen(line)+1;
  1972.    }
  1973.  
  1974. if (offset > 0)
  1975.    {
  1976.    Chop(buffer); 
  1977.    }
  1978.  
  1979. Debug("GetExecOutput got: [%s]\n",buffer);
  1980.  
  1981. cfpclose(pp);
  1982. return true; 
  1983. }
  1984.  
  1985. /********************************************************************/
  1986.  
  1987. InstallEditFile(file,edit,data)
  1988.  
  1989. char *file,*edit,*data;
  1990.  
  1991. { struct Edit *ptr;
  1992.  
  1993. if (data == NULL)
  1994.    {
  1995.    Debug1("InstallEditFile(%s,%s,-)\n",file,edit);
  1996.    }
  1997. else
  1998.    {
  1999.    Debug1("InstallEditFile(%s,%s,%s)\n",file,edit,data);
  2000.    }
  2001.  
  2002. if ( ! IsInstallable(CLASSBUFF))
  2003.    {
  2004.    InitializeAction();
  2005.    Debug1("Not installing Edit no match\n");
  2006.    return;
  2007.    }
  2008.  
  2009. bzero(VBUFF,bufsize);
  2010.  
  2011. ExpandVarstring(file,VBUFF,"");
  2012.  
  2013. if ((ptr = (struct Edit *)malloc(sizeof(struct Edit))) == NULL)
  2014.    {
  2015.    FatalError("Memory Allocation failed for InstallEditFile() #1");
  2016.    }
  2017.  
  2018. if ((ptr->fname = strdup(VBUFF)) == NULL)
  2019.    {
  2020.    FatalError("Memory Allocation failed for InstallEditFile() #2");
  2021.    }
  2022.  
  2023. if (VEDITLISTTOP == NULL)                 /* First element in the list */
  2024.    {
  2025.    VEDITLIST = ptr;
  2026.    }
  2027. else
  2028.    {
  2029.    VEDITLISTTOP->next = ptr;
  2030.    }
  2031.  
  2032. if (strncmp(VBUFF,"home",4) && strlen(VBUFF) < 6)
  2033.    {
  2034.    yyerror("Can't edit home directories: missing a filename after home");
  2035.    }
  2036.  
  2037. ptr->next = NULL;
  2038. ptr->actions = NULL;
  2039. VEDITLISTTOP = ptr;
  2040. AddEditAction(file,edit,data);
  2041. }
  2042.  
  2043. /********************************************************************/
  2044.  
  2045. AddEditAction(file,edit,data)
  2046.  
  2047. char *file,*edit,*data;
  2048.  
  2049. { struct Edit *ptr;
  2050.   struct Edlist *top,*new;
  2051.   char varbuff[bufsize];
  2052.  
  2053. if (data == NULL)
  2054.    {
  2055.    Debug2("AddEditAction(%s,%s,-)\n",file,edit);
  2056.    }
  2057. else
  2058.    {
  2059.    Debug2("AddEditAction(%s,%s,%s)\n",file,edit,data);
  2060.    }
  2061.  
  2062. if ( ! IsInstallable(CLASSBUFF))
  2063.    {
  2064.    Debug1("Not installing Edit no match\n");
  2065.    return;
  2066.    }
  2067.  
  2068. for (ptr = VEDITLIST; ptr != NULL; ptr=ptr->next)
  2069.    {
  2070.    varbuff[0] = '\0';
  2071.    ExpandVarstring(file,varbuff,"");
  2072.  
  2073.    if (strcmp(ptr->fname,varbuff) == 0)
  2074.       {
  2075.       if ((new = (struct Edlist *)malloc(sizeof(struct Edlist))) == NULL)
  2076.          {
  2077.          FatalError("Memory Allocation failed for AddEditAction() #1");
  2078.          }
  2079.  
  2080.       if (ptr->actions == NULL)
  2081.          {
  2082.          ptr->actions = new;
  2083.          }
  2084.       else
  2085.          {
  2086.          for (top = ptr->actions; top->next != NULL; top=top->next)
  2087.             {
  2088.             }
  2089.          top->next = new;
  2090.          }
  2091.  
  2092.       if (data == NULL)
  2093.          {
  2094.          new->data = NULL;
  2095.          }
  2096.       else
  2097.          {
  2098.          VBUFF[0]='\0';                         /* Expand any variables */
  2099.          ExpandVarstring(data,VBUFF,"");
  2100.  
  2101.          if ((new->data = strdup(VBUFF)) == NULL)
  2102.             {
  2103.             FatalError("Memory Allocation failed for AddEditAction() #1");
  2104.             }
  2105.          }
  2106.  
  2107.       new->next = NULL;
  2108.  
  2109.       if ((new->classes = strdup(CLASSBUFF)) == NULL)
  2110.          {
  2111.          FatalError("Memory Allocation failed for InstallEditFile() #3");
  2112.          }
  2113.  
  2114.       if ((new->code = EditActionsToCode(edit)) == NoEdit)
  2115.          {
  2116.          yyerror("Unknown edit action");
  2117.          }
  2118.  
  2119.       switch(new->code)
  2120.          {
  2121.          case BeginGroupIfNoMatch:
  2122.          case BeginGroupIfNoLineMatching:
  2123.          case BeginGroupIfNoLineContaining:
  2124.          case BeginGroupIfNoSuchLine:
  2125.      case BeginGroupIfFileIsNewer:
  2126.      case BeginGroupIfFileExists:
  2127.                 EDITGROUPLEVEL++;
  2128.                 break;
  2129.          case EndGroup:
  2130.                 EDITGROUPLEVEL--;
  2131.         if (EDITGROUPLEVEL < 0)
  2132.            {
  2133.            yyerror("EndGroup without Begin");
  2134.            }
  2135.                 break;
  2136.          case ReplaceAll:
  2137.             if (SEARCHREPLACELEVEL > 0)
  2138.            {
  2139.            yyerror("ReplaceAll without With before or at line");
  2140.            }
  2141.         
  2142.                 SEARCHREPLACELEVEL++;
  2143.                 break;
  2144.          case With:
  2145.                 SEARCHREPLACELEVEL--;
  2146.                 break;
  2147.      case ForEachLineIn:
  2148.             if (FOREACHLEVEL > 0)
  2149.            {
  2150.            yyerror("Nested ForEach loops not allowed");
  2151.            }
  2152.         
  2153.             FOREACHLEVEL++;
  2154.         break;
  2155.      case EndLoop:
  2156.             FOREACHLEVEL--;
  2157.         if (FOREACHLEVEL < 0)
  2158.            {
  2159.            yyerror("EndLoop without ForEachLineIn");
  2160.            }
  2161.         break;
  2162.      case SetLine:
  2163.             if (FOREACHLEVEL > 0)
  2164.            {
  2165.            yyerror("SetLine inside ForEachLineIn loop");
  2166.            }
  2167.             break;
  2168.      case FixEndOfLine:
  2169.             if (strlen(data) > extra_space - 1)
  2170.            {
  2171.            yyerror("End of line type is too long!");
  2172.            printf("          (max %d characters allowed)\n",extra_space);
  2173.            }
  2174.         break;
  2175.      case ReplaceLinesMatchingField:
  2176.             if (atoi(data) == 0)
  2177.            {
  2178.            yyerror("Argument must be an integer, greater than zero");
  2179.            }
  2180.      case DefineClasses:
  2181.                AddInstallable(new->data);
  2182.          }
  2183.  
  2184.       return;
  2185.       }
  2186.    }
  2187.  
  2188. printf("cfengine: software error - no file matched installing %s edit\n",file);
  2189. }
  2190.  
  2191. /********************************************************************/
  2192.  
  2193. enum editnames EditActionsToCode(edit)
  2194.  
  2195. char *edit;
  2196.  
  2197. { int i;
  2198.  
  2199. Debug2("EditActionsToCode(%s)\n",edit);
  2200.  
  2201. for (i = 0; VEDITNAMES[i] != '\0'; i++)
  2202.    {
  2203.    if (strcmp(VEDITNAMES[i],edit) == 0)
  2204.       {
  2205.       return (enum editnames) i;
  2206.       }
  2207.    }
  2208.  
  2209. return (NoEdit);
  2210. }
  2211.  
  2212.  
  2213. /********************************************************************/
  2214.  
  2215. AppendInterface(ifname,netmask,broadcast)
  2216.  
  2217. char *ifname,*netmask,*broadcast;
  2218.  
  2219. { struct Interface *ifp;
  2220.  
  2221. Debug1("Installing item (%s:%s:%s) in the interfaces list\n",ifname,netmask,broadcast);
  2222.  
  2223. if (!IsInstallable(CLASSBUFF))
  2224.    {
  2225.    InitializeAction();
  2226.    Debug1("Not installing %s, no match\n",ifname);
  2227.    return;
  2228.    }
  2229.  
  2230. if (strlen(netmask) < 7)
  2231.    {
  2232.    yyerror("illegal or missing netmask");
  2233.    InitializeAction();
  2234.    return;
  2235.    }
  2236.  
  2237. if (strlen(broadcast) < 3)
  2238.    {
  2239.    yyerror("illegal or missing broadcast address");
  2240.    InitializeAction();
  2241.    return;
  2242.    }
  2243.  
  2244. if ((ifp = (struct Interface *)malloc(sizeof(struct Interface))) == NULL)
  2245.    {
  2246.    FatalError("Memory Allocation failed for AppendInterface() #1");
  2247.    }
  2248.  
  2249. if ((ifp->classes = strdup(CLASSBUFF)) == NULL)
  2250.    {
  2251.    FatalError("Memory Allocation failed for Appendinterface() #2");
  2252.    }
  2253.  
  2254. if ((ifp->ifdev = strdup(ifname)) == NULL)
  2255.    {
  2256.    FatalError("Memory Allocation failed for AppendInterface() #3");
  2257.    }
  2258.  
  2259. if ((ifp->netmask = strdup(netmask)) == NULL)
  2260.    {
  2261.    FatalError("Memory Allocation failed for AppendInterface() #3");
  2262.    }
  2263.  
  2264. if ((ifp->broadcast = strdup(broadcast)) == NULL)
  2265.    {
  2266.    FatalError("Memory Allocation failed for AppendInterface() #3");
  2267.    } 
  2268.  
  2269. if (VIFLISTTOP == NULL)                 /* First element in the list */
  2270.    {
  2271.    VIFLIST = ifp;
  2272.    }
  2273.  else
  2274.     {
  2275.     VIFLISTTOP->next = ifp;
  2276.     }
  2277.  
  2278. ifp->next = NULL;
  2279.    
  2280. VIFLISTTOP = ifp;
  2281.  
  2282. InitializeAction(); 
  2283. }
  2284.  
  2285. /*******************************************************************/
  2286.  
  2287. AppendScript(item,timeout,useshell,uidname,gidname)
  2288.  
  2289. char *item, useshell,*uidname,*gidname;
  2290. int timeout;
  2291.  
  2292. { struct TwoDimList *tp = NULL;
  2293.   struct ShellComm *ptr;
  2294.   struct passwd *pw;
  2295.   struct group *gw;
  2296.   char *sp;
  2297.   int uid = CF_NOUSER; 
  2298.   int gid = CF_NOUSER;
  2299.   
  2300. Debug1("Installing item (%s) in the script list\n",item);
  2301.  
  2302. if ( ! IsInstallable(CLASSBUFF))
  2303.    {
  2304.    InitializeAction();
  2305.    Debug1("Not installing %s, no match\n",item);
  2306.    return;
  2307.    }
  2308.  
  2309. Build2DListFromVarstring(&tp,item,' '); /* Must be at least one space between each var */
  2310.  
  2311. Set2DList(tp);
  2312.  
  2313. for (sp = Get2DListEnt(tp); sp != NULL; sp = Get2DListEnt(tp))
  2314.    {
  2315.    if (*sp != '/')
  2316.       {
  2317.       yyerror("scripts or commands must have absolute path names");
  2318.       printf ("cfengine: concerns: %s\n",sp);
  2319.       return;
  2320.       }
  2321.  
  2322.    if ((ptr = (struct ShellComm *)malloc(sizeof(struct ShellComm))) == NULL)
  2323.       {
  2324.       FatalError("Memory Allocation failed for AppendScript() #1");
  2325.       }
  2326.  
  2327.    if ((ptr->classes = strdup(CLASSBUFF)) == NULL)
  2328.       {
  2329.       FatalError("Memory Allocation failed for Appendscript() #2");
  2330.       }
  2331.  
  2332.    if ((ptr->name = strdup(sp)) == NULL)
  2333.       {
  2334.       FatalError("Memory Allocation failed for Appendscript() #3");
  2335.       }
  2336.  
  2337.    if (VSCRIPTTOP == NULL)                 /* First element in the list */
  2338.       {
  2339.       VSCRIPT = ptr;
  2340.       }
  2341.    else
  2342.       {
  2343.       VSCRIPTTOP->next = ptr;
  2344.       }
  2345.  
  2346.  
  2347.    if (*uidname == '*')
  2348.       {
  2349.       ptr->uid = -1;      
  2350.       }
  2351.    else if (isdigit(*uidname))
  2352.       {
  2353.       sscanf(uidname,"%d",&uid);
  2354.       if (uid == CF_NOUSER)
  2355.      {
  2356.      yyerror("Unknown or silly user id");
  2357.      return;
  2358.      }
  2359.       else
  2360.      {
  2361.      ptr->uid = uid;
  2362.      }
  2363.       }
  2364.    else if ((pw = getpwnam(uidname)) == NULL)
  2365.       {
  2366.       yyerror("Unknown or silly user id");
  2367.       return;
  2368.       }
  2369.    else
  2370.       {
  2371.       ptr->uid = pw->pw_uid;
  2372.       }
  2373.  
  2374.    if (*gidname == '*')
  2375.       {
  2376.       ptr->gid = -1;
  2377.       }
  2378.    else if (isdigit(*gidname))
  2379.       {
  2380.       sscanf(gidname,"%d",&gid);
  2381.       if (gid == CF_NOUSER)
  2382.      {
  2383.      yyerror("Unknown or silly group id");
  2384.      continue;
  2385.      }
  2386.       else
  2387.      {
  2388.      ptr->gid = gid;
  2389.      }
  2390.       }
  2391.    else if ((gw = getgrnam(gidname)) == NULL)
  2392.       {
  2393.       yyerror("Unknown or silly group id");
  2394.       continue;
  2395.       }
  2396.    else
  2397.       {
  2398.       ptr->gid = gw->gr_gid;
  2399.       }
  2400.  
  2401.    ptr->log = LOGP;
  2402.    ptr->inform = INFORMP;
  2403.    ptr->timeout = timeout;
  2404.    ptr->useshell = useshell;
  2405.    ptr->next = NULL;
  2406.    
  2407.    if ((ptr->defines = strdup(ALLCLASSBUFFER)) == NULL)
  2408.       {
  2409.       FatalError("Memory Allocation failed for AppendDisable() #3");
  2410.       }
  2411.    
  2412.    AddInstallable(ptr->defines);
  2413.    VSCRIPTTOP = ptr;
  2414.    }
  2415.  
  2416. Delete2DList(tp);
  2417. }
  2418.  
  2419. /********************************************************************/
  2420.  
  2421. AppendDisable(path,type,rotate,comp,size,defines)
  2422.  
  2423. char *path, *type, comp, *defines;
  2424. short rotate;
  2425. int size;
  2426.  
  2427. { char buf2[bufsize],*sp;
  2428.   struct Disable *ptr;
  2429.   struct TwoDimList *tp = NULL;
  2430.  
  2431. Debug1("Installing item (%s) in the disable list\n",path);
  2432.  
  2433. if ( ! IsInstallable(CLASSBUFF))
  2434.    {
  2435.    InitializeAction();
  2436.    Debug1("Not installing %s, no match\n",path);
  2437.    return;
  2438.    }
  2439.  
  2440. Build2DListFromVarstring(&tp,path,' '); /* Must be at least one space between each var */
  2441.  
  2442. Set2DList(tp);
  2443.  
  2444. for (sp = Get2DListEnt(tp); sp != NULL; sp = Get2DListEnt(tp))
  2445.    {
  2446.    if (strlen(type) > 0 && strcmp(type,"plain") != 0 && strcmp(type,"file") !=0 && strcmp(type,"link") !=0
  2447.        && strcmp(type,"links") !=0 )
  2448.       {
  2449.       yyerror("Invalid file type in Disable");
  2450.       }
  2451.  
  2452.    bzero(VBUFF,bufsize);
  2453.    bzero(buf2,bufsize); 
  2454.    
  2455.    ExpandVarstring(defines,buf2,"");
  2456.    
  2457.    if ((ptr = (struct Disable *)malloc(sizeof(struct Disable))) == NULL)
  2458.       {
  2459.       FatalError("Memory Allocation failed for AppendDisable() #1");
  2460.       }
  2461.    
  2462.    if ((ptr->name = strdup(sp)) == NULL)
  2463.       {
  2464.       FatalError("Memory Allocation failed for AppendDisable() #2");
  2465.       }
  2466.    
  2467.    if ((ptr->defines = strdup(buf2)) == NULL)
  2468.       {
  2469.       FatalError("Memory Allocation failed for AppendDisable() #3");
  2470.       } 
  2471.    
  2472.    if ((ptr->classes = strdup(CLASSBUFF)) == NULL)
  2473.       {
  2474.       FatalError("Memory Allocation failed for AppendDisable() #4");
  2475.       }
  2476.    
  2477.    if (strlen(type) == 0)
  2478.       {
  2479.       sprintf(VBUFF,"all");
  2480.       }
  2481.    else
  2482.       {
  2483.       sprintf(VBUFF,"%s",type);
  2484.       }
  2485.    
  2486.    if ((ptr->type = strdup(VBUFF)) == NULL)
  2487.       {
  2488.       FatalError("Memory Allocation failed for AppendDisable() #4");
  2489.       }
  2490.    
  2491.    if (! IsItemIn(VALLADDCLASSES,buf2))
  2492.       {
  2493.       AppendItem(&VALLADDCLASSES,buf2,NULL);
  2494.       }
  2495.    
  2496.    if (VDISABLETOP == NULL)                 /* First element in the list */
  2497.       {
  2498.       VDISABLELIST = ptr;
  2499.       }
  2500.    else
  2501.       {
  2502.       VDISABLETOP->next = ptr;
  2503.       }
  2504.    
  2505.    ptr->rotate = rotate;
  2506.    ptr->comp = comp;
  2507.    ptr->size = size;
  2508.    ptr->next = NULL;
  2509.    ptr->log = LOGP;
  2510.    ptr->inform = INFORMP;
  2511.    
  2512.    VDISABLETOP = ptr;
  2513.    InitializeAction();
  2514.    AddInstallable(ptr->defines);
  2515.    }
  2516.  
  2517.  Delete2DList(tp);  
  2518. }
  2519.  
  2520. /*******************************************************************/
  2521.  
  2522. InstallTidyItem (path,wild,rec,age,travlinks,tidysize,type,ldirs,tidydirs,classes,defines)
  2523.  
  2524. char *wild, *path;
  2525. short age,tidydirs;
  2526. int rec,tidysize;
  2527. char type, ldirs, *classes, *defines, travlinks;
  2528.  
  2529. { struct TwoDimList *tp = NULL;
  2530.   char *sp;
  2531.  
  2532. if (strcmp(path,"/") != 0)
  2533.    {
  2534.    DeleteSlash(path);
  2535.    }
  2536.  
  2537. Build2DListFromVarstring(&tp,path,'/');
  2538.  
  2539. Set2DList(tp);
  2540.  
  2541. for (sp = Get2DListEnt(tp); sp != NULL; sp = Get2DListEnt(tp))
  2542.    {
  2543.    if (TidyPathExists(sp))
  2544.       {
  2545.       AddTidyItem(sp,wild,rec,age,travlinks,tidysize,type,ldirs,tidydirs,classes,defines);
  2546.       }
  2547.    else
  2548.       {
  2549.       InstallTidyPath(sp,wild,rec,age,travlinks,tidysize,type,ldirs,tidydirs,classes,defines);
  2550.       }
  2551.    }
  2552.  
  2553. Delete2DList(tp);
  2554. InitializeAction();
  2555. }
  2556.  
  2557. /*******************************************************************/
  2558.  
  2559. InstallMakePath(path,plus,minus,uidnames,gidnames,defines)
  2560.  
  2561. char *path, *defines;
  2562. mode_t plus,minus;
  2563. char *uidnames;
  2564. char *gidnames;
  2565.  
  2566. { struct File *ptr;
  2567.   char buffer[bufsize]; 
  2568.  
  2569. Debug1("InstallMakePath (%s) (+%o)(-%o)(%s)(%s)\n",path,plus,minus,uidnames,gidnames);
  2570.  
  2571. if ( ! IsInstallable(CLASSBUFF))
  2572.    {
  2573.    InitializeAction();
  2574.    Debug1("Not installing directory item, no match\n");
  2575.    return;
  2576.    }
  2577.  
  2578. VBUFF[0]='\0';                                /* Expand any variables */
  2579. ExpandVarstring(path,VBUFF,"");
  2580.  
  2581. bzero(buffer,bufsize);
  2582. ExpandVarstring(ALLCLASSBUFFER,buffer,""); 
  2583.  
  2584. if ((ptr = (struct File *)malloc(sizeof(struct File))) == NULL)
  2585.    {
  2586.    FatalError("Memory Allocation failed for InstallMakepath() #1");
  2587.    }
  2588.  
  2589. if ((ptr->path = strdup(VBUFF)) == NULL)
  2590.    {
  2591.    FatalError("Memory Allocation failed for InstallMakepath() #2");
  2592.    }
  2593.  
  2594. if ((ptr->classes = strdup(CLASSBUFF)) == NULL)
  2595.    {
  2596.    FatalError("Memory Allocation failed for InstallMakepath() #3");
  2597.    }
  2598.  
  2599. if ((ptr->defines = strdup(buffer)) == NULL)
  2600.    {
  2601.    FatalError("Memory Allocation failed for InstallMakepath() #3a");
  2602.    }
  2603.  
  2604. AddInstallable(ptr->defines); 
  2605.  
  2606. if (VMAKEPATHTOP == NULL)                 /* First element in the list */
  2607.    {
  2608.    VMAKEPATH = ptr;
  2609.    }
  2610. else
  2611.    {
  2612.    VMAKEPATHTOP->next = ptr;
  2613.    }
  2614.  
  2615. ptr->plus = plus;
  2616. ptr->minus = minus;
  2617. ptr->recurse = 0;
  2618. ptr->action = fixdirs;
  2619. ptr->uid = MakeUidList(uidnames);
  2620. ptr->gid = MakeGidList(gidnames);
  2621. ptr->inclusions = NULL;
  2622. ptr->exclusions = NULL;
  2623. ptr->acl_aliases= VACLBUILD; 
  2624. ptr->log = LOGP;
  2625. ptr->inform = INFORMP;
  2626. ptr->plus_flags = PLUSFLAG;
  2627. ptr->minus_flags = MINUSFLAG;
  2628.  
  2629. ptr->next = NULL;
  2630. VMAKEPATHTOP = ptr;
  2631. InitializeAction();
  2632. }
  2633.  
  2634. /*******************************************************************/
  2635.  
  2636. HandleTravLinks(value)
  2637.  
  2638. char *value;
  2639.  
  2640. {
  2641. if (ACTION == tidy && strncmp(CURRENTPATH,"home",4) == 0)
  2642.    {
  2643.    yyerror("Can't use links= option with special variable home in tidy");
  2644.    yyerror("Use command line options instead.\n");
  2645.    }
  2646.  
  2647. if (PTRAVLINKS != '?')
  2648.    {
  2649.    Warning("redefinition of links= option");
  2650.    }
  2651.  
  2652. if ((strcmp(value,"stop") == 0) || (strcmp(value,"false") == 0))
  2653.    {
  2654.    PTRAVLINKS = (short) 'F';
  2655.    return;
  2656.    }
  2657.  
  2658. if ((strcmp(value,"traverse") == 0) || (strcmp(value,"follow") == 0) || (strcmp(value,"true") == 0))
  2659.    {
  2660.    PTRAVLINKS = (short) 'T';
  2661.    return;
  2662.    }
  2663.  
  2664. if ((strcmp(value,"tidy"))==0)
  2665.    {
  2666.    PTRAVLINKS = (short) 'K';
  2667.    return;
  2668.    }
  2669.  
  2670. yyerror("Illegal links= specifier");
  2671. }
  2672.  
  2673. /*******************************************************************/
  2674.  
  2675. HandleTidySize(value)
  2676.  
  2677. char *value;
  2678.  
  2679. { int num = -1;
  2680.   char *sp, units = 'k';
  2681.  
  2682. for (sp = value; *sp != '\0'; sp++)
  2683.    {
  2684.    *sp = ToLower(*sp);
  2685.    }
  2686.  
  2687. if (strcmp(value,"empty") == 0)
  2688.    {
  2689.    TIDYSIZE = CF_EMPTYFILE;
  2690.    }
  2691. else
  2692.    {
  2693.    sscanf(value,"%d%c",&num,&units);
  2694.  
  2695.    if (num <= 0)
  2696.       {
  2697.       yyerror("disable/rotate value must be a decimal number >= zero or keyword empty");
  2698.       }
  2699.  
  2700.    switch (units)
  2701.       {
  2702.       case 'b': TIDYSIZE = num;
  2703.             break;
  2704.       case 'm': TIDYSIZE = num * 1024 * 1024;
  2705.             break;
  2706.       default:  TIDYSIZE = num * 1024;
  2707.       }
  2708.    }
  2709.  
  2710. }
  2711.  
  2712. /*******************************************************************/
  2713.  
  2714. HandleDisableSize(value)
  2715.  
  2716. char *value;
  2717.  
  2718. { int i = -1;
  2719.   char *sp, units = 'b';
  2720.  
  2721. for (sp = value; *sp != '\0'; sp++)
  2722.    {
  2723.    *sp = ToLower(*sp);
  2724.    }
  2725.  
  2726. switch (*value)
  2727.    {
  2728.    case '>': DISCOMP = '>';
  2729.              value++;
  2730.              break;
  2731.    case '<': DISCOMP = '<';
  2732.              value++;
  2733.              break;
  2734.    default : DISCOMP = '=';
  2735.    }
  2736.  
  2737. sscanf(value,"%d%c",&i,&units);
  2738.  
  2739. if (i < 1)
  2740.    {
  2741.    yyerror("disable size attribute with silly value (must be > 0)");
  2742.    }
  2743.  
  2744. switch (units)
  2745.    {
  2746.    case 'k': DISABLESIZE = i * 1024;
  2747.              break;
  2748.    case 'm': DISABLESIZE = i * 1024 * 1024;
  2749.              break;
  2750.    default:  DISABLESIZE = i;
  2751.    }
  2752. }
  2753.  
  2754. /*******************************************************************/
  2755.  
  2756. HandleCopySize(value)
  2757.  
  2758. char *value;
  2759.  
  2760. { int i = -1;
  2761.   char *sp, units = 'b';
  2762.  
  2763. for (sp = value; *sp != '\0'; sp++)
  2764.    {
  2765.    *sp = ToLower(*sp);
  2766.    }
  2767.  
  2768. switch (*value)
  2769.    {
  2770.    case '>': IMGCOMP = '>';
  2771.              value++;
  2772.              break;
  2773.    case '<': IMGCOMP = '<';
  2774.              value++;
  2775.              break;
  2776.    default : IMGCOMP = '=';
  2777.    }
  2778.  
  2779. sscanf(value,"%d%c",&i,&units);
  2780.  
  2781. if (i < 0)
  2782.    {
  2783.    yyerror("copy size attribute with silly value (must be a non-negative number)");
  2784.    }
  2785.  
  2786. switch (units)
  2787.    {
  2788.    case 'k': IMGSIZE = i * 1024;
  2789.              break;
  2790.    case 'm': IMGSIZE = i * 1024 * 1024;
  2791.              break;
  2792.    default:  IMGSIZE = i;
  2793.    }
  2794. }
  2795.  
  2796. /*******************************************************************/
  2797.  
  2798. HandlePurge(value)
  2799.  
  2800. char *value;
  2801.  
  2802. {
  2803. Debug1("HandlePurge(%s)\n",value);
  2804.   
  2805. if ((strcmp(value,"true") == 0) || (strcmp(value,"on") == 0))
  2806.    {
  2807.    PURGE = 'y';
  2808.    return;
  2809.    }
  2810.  
  2811. if ((strcmp(value,"false") == 0) || (strcmp(value,"off") == 0))
  2812.    {
  2813.    PURGE = 'n';
  2814.    return;
  2815.    }
  2816.  
  2817. yyerror("Illegal purge value");
  2818. }
  2819.  
  2820. /*******************************************************************/
  2821.  
  2822. HandleRequiredSize(value)
  2823.  
  2824. char *value;
  2825.  
  2826. { int i = -1;
  2827.   char *sp, units = 'b';
  2828.  
  2829. for (sp = value; *sp != '\0'; sp++)
  2830.    {
  2831.    *sp = ToLower(*sp);
  2832.    }
  2833.  
  2834. switch (*value)
  2835.    {
  2836.    case '>': IMGCOMP = '>';
  2837.              value++;
  2838.              break;
  2839.    case '<': IMGCOMP = '<';
  2840.              value++;
  2841.              break;
  2842.    default : IMGCOMP = '=';
  2843.    }
  2844.  
  2845. sscanf(value,"%d%c",&i,&units);
  2846.  
  2847. if (i < 1)
  2848.    {
  2849.    yyerror("disk/required size attribute with silly value (must be > 0)");
  2850.    }
  2851.  
  2852. switch (units)
  2853.    {
  2854.    case 'b': IMGSIZE = i / 1024;
  2855.              break;
  2856.    case 'm': IMGSIZE = i * 1024;
  2857.              break;
  2858.    case '%': IMGSIZE = -i;       /* -ve number signals percentage */
  2859.              break;
  2860.    default:  IMGSIZE = i;
  2861.    }
  2862. }
  2863.  
  2864. /*******************************************************************/
  2865.  
  2866. HandleTidyType(value)
  2867.  
  2868. char *value;
  2869.  
  2870. {
  2871. if (strcmp(value,"a")== 0 || strcmp(value,"atime") == 0)
  2872.    {
  2873.    AGETYPE = 'a';
  2874.    return;
  2875.    }
  2876.  
  2877. if (strcmp(value,"m")== 0 || strcmp(value,"mtime") == 0)
  2878.    {
  2879.    AGETYPE = 'm';
  2880.    return;
  2881.    }
  2882.  
  2883. if (strcmp(value,"c")== 0 || strcmp(value,"ctime") == 0)
  2884.    {
  2885.    AGETYPE = 'c';
  2886.    return;
  2887.    }
  2888.  
  2889. yyerror("Illegal age search type, must be atime/ctime/mtime");
  2890. }
  2891.  
  2892. /*******************************************************************/
  2893.  
  2894. HandleTidyLinkDirs(value)
  2895.  
  2896. char *value;
  2897.  
  2898. {
  2899. if (strcmp(value,"keep")== 0)
  2900.    {
  2901.    LINKDIRS = 'k';
  2902.    return;
  2903.    }
  2904.  
  2905. if (strcmp(value,"tidy")== 0 || strcmp(value,"delete") == 0)
  2906.    {
  2907.    LINKDIRS = 't';
  2908.    return;
  2909.    }
  2910.  
  2911. yyerror("Illegal linkdirs value, must be keep/delete/tidy");
  2912. }
  2913.  
  2914. /*******************************************************************/
  2915.  
  2916. HandleTidyRmdirs(value)
  2917.  
  2918. char *value;
  2919.  
  2920. {
  2921. if ((strcmp(value,"true") == 0)||(strcmp(value,"all") == 0))
  2922.    {
  2923.    TIDYDIRS = 1;
  2924.    return;
  2925.    }
  2926.  
  2927. if ((strcmp(value,"false") == 0)||(strcmp(value,"none") == 0))
  2928.    {
  2929.    TIDYDIRS = 0;
  2930.    return;
  2931.    }
  2932.  
  2933. if (strcmp(value,"sub") == 0)
  2934.    {
  2935.    TIDYDIRS = 2;
  2936.    return;
  2937.    }
  2938.  
  2939. yyerror("Illegal rmdirs value, must be true/false");
  2940. }
  2941.  
  2942. /*******************************************************************/
  2943.  
  2944. HandleForceCopy(value)
  2945.  
  2946. char *value;
  2947.  
  2948. {
  2949. if (strcmp(value,"true") == 0 || strcmp(value,"on") == 0)
  2950.    {
  2951.    FORCECOPY = true;
  2952.    return;
  2953.    }
  2954.  
  2955. if (strcmp(value,"false") == 0 || strcmp(value,"off") == 0)
  2956.    {
  2957.    FORCECOPY = false;
  2958.    return;
  2959.    }
  2960.  
  2961. yyerror("Illegal copy attribute for force= ");
  2962. }
  2963.  
  2964. /*******************************************************************/
  2965.  
  2966. HandleCopyBackup(value)
  2967.  
  2968. char *value;
  2969.  
  2970. {
  2971. if (strcmp(value,"true") == 0 || strcmp(value,"on") == 0)
  2972.    {
  2973.    IMAGEBACKUP = true;
  2974.    return;
  2975.    }
  2976.  
  2977. if (strcmp(value,"false") == 0 || strcmp(value,"off") == 0)
  2978.    {
  2979.    IMAGEBACKUP = false;
  2980.    return;
  2981.    }
  2982.  
  2983. yyerror("Illegal copy attribute for backup= ");
  2984. }
  2985.  
  2986. /*******************************************************************/
  2987.  
  2988. HandleTimeOut(value)
  2989.  
  2990. char *value;
  2991.  
  2992. { int num = -1;
  2993.  
  2994. sscanf(value,"%d",&num);
  2995.  
  2996. if (num <= 0)
  2997.    {
  2998.    yyerror("timeout value must be a decimal number > 0");
  2999.    }
  3000.  
  3001. VTIMEOUT = num;
  3002. }
  3003.  
  3004.  
  3005. /*******************************************************************/
  3006.  
  3007. HandleUseShell(value)
  3008.  
  3009. char *value;
  3010.  
  3011. {
  3012.  if (strcmp(value,"true") == 0)
  3013.    {
  3014.    USESHELL = 'y';
  3015.    return;
  3016.    }
  3017.  
  3018. if (strcmp(value,"false") == 0)
  3019.    {
  3020.    USESHELL = 'n';
  3021.    return;
  3022.    }
  3023.  
  3024. if (strcmp(value,"dumb") == 0)
  3025.    {
  3026.    USESHELL = 'd';
  3027.    return;
  3028.    }
  3029.  
  3030. yyerror("Illegal attribute for useshell= ");
  3031. }
  3032.  
  3033. /*******************************************************************/
  3034.  
  3035. HandleSetLog(value)
  3036.  
  3037. char *value;
  3038.  
  3039. {
  3040. if (strcmp(value,"true") == 0 || strcmp(value,"on") == 0)
  3041.    {
  3042.    LOGP = 't';
  3043.    return;
  3044.    }
  3045.  
  3046. if (strcmp(value,"false") == 0 || strcmp(value,"off") == 0)
  3047.    {
  3048.    LOGP = 'f';
  3049.    return;
  3050.    }
  3051.  
  3052. yyerror("Illegal attribute for log= ");
  3053. }
  3054.  
  3055. /*******************************************************************/
  3056.  
  3057. HandleSetInform(value)
  3058.  
  3059. char *value;
  3060.  
  3061. {
  3062. if (strcmp(value,"true") == 0 || strcmp(value,"on") == 0)
  3063.    {
  3064.    INFORMP = 't';
  3065.    return;
  3066.    }
  3067.  
  3068. if (strcmp(value,"false") == 0 || strcmp(value,"off") == 0)
  3069.    {
  3070.    INFORMP = 'f';
  3071.    return;
  3072.    }
  3073.  
  3074. yyerror("Illegal attribute for inform= ");
  3075. }
  3076.  
  3077. /*******************************************************************/
  3078.  
  3079. HandleSetSecure(value)
  3080.  
  3081. char *value;
  3082.  
  3083. {
  3084. if (strcmp(value,"true") == 0 || strcmp(value,"on") == 0)
  3085.    {
  3086.    SECURE = true;
  3087.    return;
  3088.    }
  3089.  
  3090. if (strcmp(value,"false") == 0 || strcmp(value,"off") == 0)
  3091.    {
  3092.    SECURE = false;
  3093.    return;
  3094.    }
  3095.  
  3096. yyerror("Illegal attribute for secure= ");
  3097. }
  3098.  
  3099. /*******************************************************************/
  3100.  
  3101. HandleChecksum(value)
  3102.  
  3103. char *value;
  3104.  
  3105. {
  3106. if (strcmp(value,"md5") == 0)
  3107.    {
  3108.    CHECKSUM = 'm';
  3109.    return;
  3110.    }
  3111.  
  3112. yyerror("Illegal attribute for checksum= ");
  3113. }
  3114.  
  3115. /*******************************************************************/
  3116.  
  3117. HandleStealth(value)
  3118.  
  3119. char *value;
  3120.  
  3121. {
  3122. if (strcmp(value,"true") == 0 || strcmp(value,"on") == 0)
  3123.    {
  3124.    STEALTH = 't';
  3125.    return;
  3126.    }
  3127.  
  3128. if (strcmp(value,"false") == 0 || strcmp(value,"off") == 0)
  3129.    {
  3130.    STEALTH = 'f';
  3131.    return;
  3132.    }
  3133.  
  3134. yyerror("Illegal attribute for stealth= ");
  3135. }
  3136.  
  3137.  
  3138. /*******************************************************************/
  3139.  
  3140. GetFileAction(action)
  3141.  
  3142. char *action;
  3143.  
  3144. { int i;
  3145.  
  3146. for (i = 0; FILEACTIONTEXT[i] != '\0'; i++)
  3147.    {
  3148.    if (strcmp(action,FILEACTIONTEXT[i]) == 0)
  3149.       {
  3150.       return i;
  3151.       }
  3152.    }
  3153.  
  3154. yyerror("Unknown action type");
  3155. return (int) warnall;
  3156. }
  3157.  
  3158.  
  3159. /*******************************************************************/
  3160.  
  3161. InstallFileListItem(path,plus,minus,action,uidnames,gidnames,recurse,travlinks,defines,chksum)
  3162.  
  3163. char *path, *defines;
  3164. mode_t plus,minus;
  3165. enum fileactions action;
  3166. char *uidnames;
  3167. char *gidnames;
  3168. int recurse;
  3169. char travlinks,chksum;
  3170.  
  3171. { struct File *ptr;
  3172.   char *spl;
  3173.   struct TwoDimList *tp = NULL;
  3174.  
  3175. Debug1("InstallFileaction (%s) (+%o)(-%o) (%s) (%d) (%c)\n",path,plus,minus,FILEACTIONTEXT[action],action,travlinks);
  3176.  
  3177. if ( ! IsInstallable(CLASSBUFF))
  3178.    {
  3179.    InitializeAction();
  3180.    Debug1("Not installing file item, no match\n");
  3181.    return;
  3182.    }
  3183.  
  3184. bzero(VBUFF,bufsize);
  3185. ExpandVarstring(ALLCLASSBUFFER,VBUFF,""); 
  3186.  
  3187. Build2DListFromVarstring(&tp,path,'/');
  3188.     
  3189. Set2DList(tp);
  3190.  
  3191. for (spl = Get2DListEnt(tp); spl != NULL; spl = Get2DListEnt(tp))
  3192.    {
  3193.    if ((ptr = (struct File *)malloc(sizeof(struct File))) == NULL)
  3194.       {
  3195.       FatalError("Memory Allocation failed for InstallFileListItem() #1");
  3196.       }
  3197.  
  3198.    if ((ptr->path = strdup(spl)) == NULL)
  3199.       {
  3200.       FatalError("Memory Allocation failed for InstallFileListItem() #2");
  3201.       }
  3202.  
  3203.    if ((ptr->classes = strdup(CLASSBUFF)) == NULL)
  3204.       {
  3205.       FatalError("Memory Allocation failed for InstallFileListItem() #3");
  3206.       }
  3207.  
  3208.    if ((ptr->defines = strdup(VBUFF)) == NULL)
  3209.       {
  3210.       FatalError("Memory Allocation failed for InstallFileListItem() #3");
  3211.       }
  3212.  
  3213.    AddInstallable(ptr->defines);
  3214.  
  3215.    if (VFILETOP == NULL)                 /* First element in the list */
  3216.       {
  3217.       VFILE = ptr;
  3218.       }
  3219.    else
  3220.       {
  3221.       VFILETOP->next = ptr;
  3222.       }
  3223.  
  3224.    ptr->action = action;
  3225.    ptr->plus = plus;
  3226.    ptr->minus = minus;
  3227.    ptr->recurse = recurse;
  3228.    ptr->uid = MakeUidList(uidnames);
  3229.    ptr->gid = MakeGidList(gidnames);
  3230.    ptr->exclusions = VEXCLUDEPARSE;
  3231.    ptr->inclusions = VINCLUDEPARSE;
  3232.    ptr->ignores = VIGNOREPARSE;
  3233.    ptr->travlinks = travlinks;
  3234.    ptr->acl_aliases  = VACLBUILD;
  3235.    ptr->next = NULL;
  3236.    ptr->log = LOGP;
  3237.    ptr->inform = INFORMP;
  3238.    ptr->checksum = chksum;
  3239.    ptr->plus_flags = PLUSFLAG;
  3240.    ptr->minus_flags = MINUSFLAG;
  3241.  
  3242.    VFILETOP = ptr;
  3243.    Debug1("Installed file object %s\n",spl);
  3244.    }
  3245.  
  3246. Delete2DList(tp);
  3247.  
  3248. InitializeAction();
  3249. }
  3250.  
  3251.  
  3252. /*******************************************************************/
  3253.  
  3254. InstallProcessItem(expr,restart,matches,comp,signal,action,classes,defines,useshell)
  3255.  
  3256. char *expr, *restart, *classes, *defines;
  3257. short matches, signal;
  3258. char action, comp, useshell;
  3259.  
  3260. { struct Process *ptr;
  3261.   char buf1[bufsize], buf2[bufsize], buf3[bufsize];
  3262.  
  3263. if (comp == 't')
  3264.    {
  3265.    comp = '=';
  3266.    }
  3267.  
  3268. Debug1("InstallProcessItem(%s,%s,%d,%d,%c)\n",expr,restart,matches,signal,action);
  3269.  
  3270. bzero(buf1,bufsize);
  3271. bzero(buf2,bufsize);
  3272. bzero(buf3,bufsize); 
  3273.  
  3274. ExpandVarstring(expr,buf1,"");
  3275. ExpandVarstring(restart,buf2,"");
  3276. ExpandVarstring(defines,buf3,""); 
  3277.  
  3278. if ( ! IsInstallable(CLASSBUFF))
  3279.    {
  3280.    InitializeAction();
  3281.    Debug1("Not installing process item, no match\n");
  3282.    return;
  3283.    }
  3284.  
  3285. if ((ptr = (struct Process *)malloc(sizeof(struct Process))) == NULL)
  3286.    {
  3287.    FatalError("Memory Allocation failed for InstallProcItem() #1");
  3288.    }
  3289.  
  3290. if ((ptr->expr = strdup(buf1)) == NULL)
  3291.    {
  3292.    FatalError("Memory Allocation failed for InstallProcItem() #2");
  3293.    }
  3294.  
  3295. if ((ptr->restart = strdup(buf2)) == NULL)
  3296.    {
  3297.    FatalError("Memory Allocation failed for InstallProcItem() #3");
  3298.    }
  3299.  
  3300. if ((ptr->defines = strdup(buf3)) == NULL)
  3301.    {
  3302.    FatalError("Memory Allocation failed for InstallProcItem() #4");
  3303.    }
  3304.  
  3305. if ((ptr->classes = strdup(CLASSBUFF)) == NULL)
  3306.    {
  3307.    FatalError("Memory Allocation failed for InstallProcItem() #5");
  3308.    }
  3309.  
  3310. if (VPROCTOP == NULL)                 /* First element in the list */
  3311.    {
  3312.    VPROCLIST = ptr;
  3313.    }
  3314. else
  3315.    {
  3316.    VPROCTOP->next = ptr;
  3317.    }
  3318.  
  3319. if (! IsItemIn(VALLADDCLASSES,buf3))
  3320.    {
  3321.    AppendItem(&VALLADDCLASSES,buf3,NULL);
  3322.    }
  3323.  
  3324. ptr->matches = matches;
  3325. ptr->comp = comp;
  3326. ptr->signal = signal;
  3327. ptr->action = action;
  3328. ptr->useshell = useshell; 
  3329. ptr->next = NULL;
  3330. ptr->log = LOGP;
  3331. ptr->inform = INFORMP;
  3332. ptr->exclusions = VEXCLUDEPARSE;
  3333. ptr->inclusions = VINCLUDEPARSE;
  3334. VPROCTOP = ptr;
  3335. InitializeAction();
  3336. AddInstallable(ptr->defines); 
  3337. }
  3338.  
  3339. /*******************************************************************/
  3340.  
  3341. InstallImageItem(path,plus,minus,destination,action,uidnames,gidnames,
  3342.          force,size,comp,backup,rec,type,lntype,server,classbuffer,
  3343.          purge,stealth,secure)
  3344.  
  3345. char *path, *destination, *action, *server, *classbuffer;
  3346. mode_t plus,minus;
  3347. char *uidnames;
  3348. char *gidnames;
  3349. short force;
  3350. short backup;
  3351. char type, lntype, comp, purge, stealth;
  3352. int rec, size;
  3353. short secure;
  3354.  
  3355. { struct Image *ptr;
  3356.   char *sp, *spl; 
  3357.   char buf1[bufsize], buf2[bufsize], buf3[bufsize], buf4[bufsize];
  3358.   struct TwoDimList *tp = NULL, *tpserv = NULL;
  3359.   int i;
  3360.   struct hostent *hp;
  3361.   
  3362. if ( ! IsInstallable(CLASSBUFF))
  3363.    {
  3364.    InitializeAction();
  3365.    Debug1("Not installing copy item, no match\n");
  3366.    return;
  3367.    }
  3368.   
  3369. Debug1("InstallImageItem (%s) (+%o)(-%o) (%s), server=%s\n",path,plus,minus,destination,server);
  3370.  
  3371. if (strlen(action) == 0)   /* default action */
  3372.    {
  3373.    strcat(action,"fix");
  3374.    }
  3375.  
  3376. if (!(strcmp(action,"silent") == 0 || strcmp(action,"warn") == 0 || strcmp(action,"fix") == 0))
  3377.    {
  3378.    sprintf(VBUFF,"Illegal action in image/copy item: %s",action);
  3379.    yyerror(VBUFF);
  3380.    return;
  3381.    }
  3382.  
  3383. bzero(buf1,bufsize);
  3384. bzero(buf3,bufsize);
  3385. bzero(buf4,bufsize);
  3386.  
  3387. ExpandVarstring(path,buf1,"");
  3388. ExpandVarstring(server,buf3,"");
  3389. ExpandVarstring(classbuffer,buf4,"");
  3390.  
  3391. if (strlen(buf1) > 1)
  3392.    {
  3393.    DeleteSlash(buf1);
  3394.    }
  3395.  
  3396. if (!FORCENETCOPY && ((strcmp(buf3,VFQNAME) == 0) || (strcmp(buf3,VUQNAME) == 0) || (strcmp(buf3,VSYSNAME.nodename) == 0)))
  3397.    {
  3398.    Debug("Swapping %s for localhost\n",server);
  3399.    strcpy(buf3,"localhost");
  3400.    }
  3401.  
  3402.  
  3403. Build2DListFromVarstring(&tp,path,'/');  /* Must split on space in comm string */
  3404.     
  3405. Set2DList(tp);
  3406.  
  3407. if ((ptr = (struct Image *)malloc(sizeof(struct Image))) == NULL)
  3408.    {
  3409.    FatalError("Memory Allocation failed for InstallImageItem() #1");
  3410.    }
  3411.  
  3412. if ((ptr->classes = strdup(CLASSBUFF)) == NULL)
  3413.    {
  3414.    FatalError("Memory Allocation failed for InstallImageItem() #3");
  3415.    }
  3416.  
  3417. if (strlen(buf3) > 128)
  3418.    {
  3419.    yyerror("Server name is too long");
  3420.    return;
  3421.    }
  3422.  
  3423. if ((ptr->server = strdup(buf3)) == NULL)
  3424.    {
  3425.    FatalError("Memory Allocation failed for InstallImageItem() #5");
  3426.    }
  3427.  
  3428. if ((ptr->action = strdup(action)) == NULL)
  3429.    {
  3430.    FatalError("Memory Allocation failed for InstallImageItem() #6");
  3431.    }
  3432.  
  3433. if ((ptr->defines = strdup(buf4)) == NULL)
  3434.    {
  3435.    FatalError("Memory Allocation failed for InstallImageItem() #7");
  3436.    }
  3437.  
  3438. for (spl = Get2DListEnt(tp); spl != NULL; spl = Get2DListEnt(tp))
  3439.    {
  3440.    if (strlen(destination) == 0)
  3441.       {
  3442.       strcpy(buf2,spl);
  3443.       }
  3444.    else
  3445.       {
  3446.       bzero(buf2,bufsize);
  3447.       ExpandVarstring(destination,buf2,"");
  3448.       }
  3449.  
  3450.    if (strlen(buf2) > 1)
  3451.    {
  3452.    DeleteSlash(buf2);
  3453.    }
  3454.  
  3455.    if (buf2[0] != '/')
  3456.       {
  3457.       if (strncmp(buf2,"home",4) == 0)
  3458.      {
  3459.      if (strlen(buf2) > 4 && buf2[4] != '/')
  3460.         {
  3461.         yyerror("illegal use of home or not absolute pathname");
  3462.         return;
  3463.         }
  3464.      }
  3465.       else
  3466.      {
  3467.      yyerror("Image needs an absolute pathname");
  3468.      return;
  3469.      }
  3470.       }
  3471.  
  3472.    if ((ptr->destination = strdup(buf2)) == NULL)
  3473.       {
  3474.       FatalError("Memory Allocation failed for InstallImageItem() #4");
  3475.       }
  3476.  
  3477.    if ((strcmp(spl,buf2) == 0) && (strcmp(buf3,"localhost") == 0))
  3478.       {
  3479.       yyerror("image loop: file/dir copies to itself or missing destination file");
  3480.       return;
  3481.       }
  3482.  
  3483.    if ((ptr->path = strdup(spl)) == NULL)
  3484.       {
  3485.       FatalError("Memory Allocation failed for InstallImageItem() #2");
  3486.       }
  3487.       
  3488.    if (VIMAGETOP == NULL)
  3489.       {
  3490.       VIMAGE = ptr;
  3491.       }
  3492.    else
  3493.       {
  3494.       VIMAGETOP->next = ptr;
  3495.       }
  3496.  
  3497.    ptr->plus = plus;
  3498.    ptr->minus = minus;
  3499.    ptr->uid = MakeUidList(uidnames);
  3500.    ptr->gid = MakeGidList(gidnames);
  3501.    ptr->force = force;
  3502.    ptr->next = NULL;
  3503.    ptr->backup = backup;
  3504.    ptr->recurse = rec;
  3505.    ptr->type = type;
  3506.    ptr->stealth = stealth;
  3507. #ifdef HAVE_LIBCRYPTO
  3508.    ptr->secure = secure;
  3509. #else
  3510.    ptr->secure = false;
  3511.    Verbose("Secure copying is not possible without libcrypto from OpenSSL\n");
  3512. #endif
  3513.    ptr->size = size;
  3514.    ptr->comp = comp;
  3515.    ptr->linktype = lntype;
  3516.    ptr->symlink = VCPLNPARSE;
  3517.    ptr->exclusions = VEXCLUDEPARSE;
  3518.    ptr->inclusions = VINCLUDEPARSE;
  3519.    ptr->ignores = VIGNOREPARSE;
  3520.    ptr->cache = NULL;
  3521.    ptr->purge = purge;
  3522.    ptr->log = LOGP;
  3523.    ptr->inform = INFORMP;
  3524.    ptr->plus_flags = PLUSFLAG;
  3525.    ptr->minus_flags = MINUSFLAG;
  3526.  
  3527.    if (purge == 'y' && strcmp(buf3,"localhost") == 0)
  3528.       {
  3529.       Verbose("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
  3530.       Verbose("!! Purge detected in local (non-cfd) file copy to file %s\n",ptr->destination);
  3531.       Verbose("!! Do not risk purge if source %s is NFS mounted (see manual)\n",ptr->path);
  3532.       Verbose("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
  3533.       }
  3534.  
  3535.    ptr->acl_aliases = VACLBUILD;
  3536.    
  3537.    if (strcmp(buf3,"localhost") != 0)
  3538.       {
  3539.       if ((hp = gethostbyname(buf3)) == NULL)
  3540.      {
  3541.      yyerror("DNS lookup failure. Unknown host");
  3542.      printf("Culprit: %s\n",server);
  3543.      printf("Make sure that fully qualified names can be looked up at your site!\n");
  3544.      printf("i.e. prep.ai.mit.edu, not just prep. If you use NIS or /etc/hosts\n");
  3545.      printf("make sure that the full form is registered too as an alias!\n");
  3546.      perror("gethostbyname: ");
  3547.      exit(1);
  3548.      }
  3549.       
  3550.       ptr->dns = (struct in_addr *) malloc(sizeof(struct in_addr));
  3551.       
  3552.       bcopy((hp->h_addr),(ptr->dns),sizeof(struct in_addr));
  3553.       }
  3554.    else
  3555.       {
  3556.       ptr->dns = NULL;
  3557.       }
  3558.    
  3559.    ptr->inode_cache = NULL;
  3560.    
  3561.    VIMAGETOP = ptr;
  3562.  
  3563.    AddInstallable(ptr->defines);
  3564.  
  3565.    if (!IsItemIn(VSERVERLIST,ptr->server))   /* cache list of servers */
  3566.       {
  3567.       AppendItem(&VSERVERLIST,ptr->server,NULL);
  3568.       }
  3569.    }
  3570.  
  3571. /* Add to possible classes so actions will be installed */
  3572.  
  3573.    
  3574. Delete2DList(tp);
  3575.  
  3576. InitializeAction();
  3577. }
  3578.  
  3579. /*******************************************************************/
  3580.  
  3581. InstallAuthItem(path,attribute,list,listtop,classes)
  3582.  
  3583. char *path, *attribute, *classes;
  3584. struct Auth **list, **listtop;
  3585.  
  3586. { struct TwoDimList *tp = NULL;
  3587.   char *sp;
  3588.  
  3589. Debug1("InstallAuthItem(%s,%s)\n",path,attribute);
  3590.  
  3591. Build2DListFromVarstring(&tp,path,'/');
  3592.    
  3593. Set2DList(tp);
  3594.  
  3595. for (sp = Get2DListEnt(tp); sp != NULL; sp = Get2DListEnt(tp))
  3596.    {
  3597.    if (AuthPathExists(sp,*list))
  3598.       {
  3599.       AddAuthHostItem(sp,attribute,classes,list);
  3600.       }
  3601.    else
  3602.       {
  3603.       InstallAuthPath(sp,attribute,classes,list,listtop);
  3604.       }
  3605.    }
  3606.  
  3607. Delete2DList(tp);
  3608. }
  3609.  
  3610. /*******************************************************************/
  3611.  
  3612. GetCommAttribute(s)
  3613.  
  3614. char *s;
  3615.  
  3616. { int i;
  3617.   char comm[maxvarsize];
  3618.  
  3619. for (i = 0; s[i] != '\0'; i++)
  3620.    {
  3621.    s[i] = ToLower(s[i]);
  3622.    }
  3623.  
  3624. comm[0]='\0';
  3625.  
  3626. sscanf(s,"%[^=]",comm);
  3627.  
  3628. Debug1("GetCommAttribute(%s)\n",comm);
  3629.  
  3630. for (i = 0; COMMATTRIBUTES[i] != NULL; i++)
  3631.    {
  3632.    if (strncmp(COMMATTRIBUTES[i],comm,strlen(comm)) == 0)
  3633.       {
  3634.       Debug1("GetCommAttribute - got: %s\n",COMMATTRIBUTES[i]);
  3635.       return i;
  3636.       }
  3637.    }
  3638.  
  3639. return cfbad;
  3640. }
  3641.  
  3642. /*******************************************************************/
  3643.  
  3644. HandleRecurse(value)
  3645.  
  3646. char *value;
  3647.  
  3648. { int n = -1;
  3649.  
  3650. if (strcmp(value,"inf") == 0)
  3651.    {
  3652.    VRECURSE = INFINITERECURSE;
  3653.    }
  3654. else
  3655.    {
  3656.    if (strncmp(CURRENTPATH,"home",4) == 0)
  3657.       {
  3658.       yyerror("Recursion is always infinite for home");
  3659.       return;
  3660.       }
  3661.  
  3662.    sscanf(value,"%d",&n);
  3663.  
  3664.    if (n == -1)
  3665.       {
  3666.       yyerror("Illegal recursion specifier");
  3667.       }
  3668.    else
  3669.       {
  3670.       VRECURSE = n;
  3671.       }
  3672.    }
  3673. }
  3674.  
  3675. /*******************************************************************/
  3676.  
  3677. HandleCopyType(value)
  3678.  
  3679. char *value;
  3680.  
  3681. {
  3682. if (strcmp(value,"ctime") == 0)
  3683.    {
  3684.    Debug1("Set copy by ctime\n");
  3685.    COPYTYPE = 't';
  3686.    return;
  3687.    }
  3688. else if (strcmp(value,"mtime") == 0)
  3689.    {
  3690.    Debug1("Set copy by mtime\n");
  3691.    COPYTYPE = 'm';
  3692.    return;
  3693.    }
  3694.  else if (strcmp(value,"checksum")==0 || strcmp(value,"sum") == 0)
  3695.    {
  3696.    Debug1("Set copy by md5 checksum\n");
  3697.    COPYTYPE = 'c';
  3698.    return;
  3699.    }
  3700. else if (strcmp(value,"byte")==0 || strcmp(value,"binary") == 0)
  3701.    {
  3702.    Debug1("Set copy by byte comaprison\n");
  3703.    COPYTYPE = 'b';
  3704.    return;
  3705.    }
  3706. yyerror("Illegal copy type");
  3707. }
  3708.  
  3709. /*******************************************************************/
  3710.  
  3711. HandleDisableFileType(value)
  3712.  
  3713. char *value;
  3714.  
  3715. {
  3716. if (strlen(CURRENTITEM) != 0)
  3717.    {
  3718.    Warning("Redefinition of filetype in disable");
  3719.    }
  3720.  
  3721. if (strcmp(value,"link") == 0 || strcmp(value,"links") == 0)
  3722.    {
  3723.    strcpy(CURRENTITEM,"link");
  3724.    }
  3725. else if (strcmp(value,"plain") == 0 || strcmp(value,"file") == 0)
  3726.    {
  3727.    strcpy(CURRENTITEM,"file");
  3728.    }
  3729. else
  3730.    {
  3731.    yyerror("Disable filetype unknown");
  3732.    }
  3733. }
  3734.  
  3735. /*******************************************************************/
  3736.  
  3737. HandleDisableRotate(value)
  3738.  
  3739. char *value;
  3740.  
  3741. { int num = 0;
  3742.  
  3743. if (strcmp(value,"empty") == 0 || strcmp(value,"truncate") == 0)
  3744.    {
  3745.    ROTATE = CF_TRUNCATE;
  3746.    }
  3747. else
  3748.    {
  3749.    sscanf(value,"%d",&num);
  3750.  
  3751.    if (num == 0)
  3752.       {
  3753.       yyerror("disable/rotate value must be a decimal number greater than zero or keyword empty");
  3754.       }
  3755.  
  3756.    if (! SILENT && num > 99)
  3757.       {
  3758.       Warning("rotate value looks silly");
  3759.       }
  3760.  
  3761.    ROTATE = (short) num;
  3762.    }
  3763. }
  3764.  
  3765. /*******************************************************************/
  3766.  
  3767. HandleAge(days)
  3768.  
  3769. char *days;
  3770.  
  3771. sscanf(days,"%d",&VAGE);
  3772. Debug1("HandleAge(%d)\n",VAGE);
  3773. }
  3774.  
  3775. /*******************************************************************/
  3776.  
  3777. HandleProcessMatches(value)
  3778.  
  3779. char *value;
  3780.  
  3781. { int i = -1;
  3782.  
  3783. switch (*value)
  3784.    {
  3785.    case '>': PROCOMP = '>';
  3786.              value++;
  3787.              break;
  3788.    case '<': PROCOMP = '<';
  3789.              value++;
  3790.              break;
  3791.    default : PROCOMP = '=';
  3792.    }
  3793.  
  3794. sscanf(value,"%d",&i);
  3795.  
  3796. if (i < 0) 
  3797.    {
  3798.    yyerror("matches attribute with silly value (must be >= 0)");
  3799.    }
  3800.  
  3801. PROMATCHES = (short) i;
  3802. }
  3803.  
  3804. /*******************************************************************/
  3805.  
  3806. HandleProcessSignal(value)
  3807.  
  3808. char *value;
  3809.  
  3810. { int i;
  3811.   char *sp;
  3812.  
  3813. for (i = 1; SIGNALS[i] != 0; i++)
  3814.    {
  3815.    for (sp = value; *sp != '\0'; sp++)
  3816.       {
  3817.       *sp = ToUpper(*sp);
  3818.       }
  3819.    
  3820.    if (strcmp(SIGNALS[i]+3,value) == 0)  /* 3 to cut off "sig" */
  3821.       {
  3822.       PROSIGNAL = (short) i;
  3823.       return;
  3824.       }
  3825.    }
  3826.  
  3827. i = 0;
  3828.  
  3829. sscanf(value,"%d",&i);
  3830.  
  3831. if (i < 1 && i > highest_signal)
  3832.    {
  3833.    yyerror("Unknown signal in attribute");
  3834.    }
  3835.  
  3836. PROSIGNAL = (short) i;
  3837. }
  3838.  
  3839. /*******************************************************************/
  3840.  
  3841. HandleNetmask(value)
  3842.  
  3843. char *value;
  3844.  
  3845. {
  3846.  if (strlen(DESTINATION) == 0)
  3847.     {
  3848.     strcpy(DESTINATION,value);
  3849.     }
  3850.  else
  3851.     {
  3852.     yyerror("redefinition of netmask");
  3853.     }
  3854. }
  3855.  
  3856. /*******************************************************************/
  3857.  
  3858. HandleBroadcast(value)
  3859.  
  3860. char *value;
  3861.  
  3862. {
  3863. if (strlen(CURRENTPATH) != 0)
  3864.     {
  3865.     yyerror("redefinition of broadcast address");
  3866.     }
  3867.  
  3868. if (strcmp("ones",value) == 0)
  3869.    {
  3870.    strcpy(CURRENTPATH,"one");
  3871.    return;
  3872.    }
  3873.  
  3874. if (strcmp("zeroes",value) == 0)
  3875.    {
  3876.    strcpy(CURRENTPATH,"zero");
  3877.    return;
  3878.    }
  3879.  
  3880. if (strcmp("zeros",value) == 0)
  3881.    {
  3882.    strcpy(CURRENTPATH,"zero");
  3883.    return;
  3884.    }
  3885.  
  3886. yyerror("Illegal broadcast specifier (ones/zeros)"); 
  3887. }
  3888.  
  3889. /*******************************************************************/
  3890.  
  3891. AppendToActionSequence (action)
  3892.  
  3893. char *action;
  3894.  
  3895. { int j = 0;
  3896.   char *sp,cbuff[bufsize],actiontxt[bufsize];
  3897.  
  3898. Debug1("Installing item (%s) in the action sequence list\n",action);
  3899.  
  3900. AppendItem(&VACTIONSEQ,action,CLASSBUFF);
  3901.  
  3902. cbuff[0]='\0';
  3903. actiontxt[0]='\0';
  3904. sp = action;
  3905.  
  3906. while (*sp != '\0')
  3907.    {
  3908.    ++j;
  3909.    sscanf(sp,"%[^.]",cbuff);
  3910.  
  3911.    while ((*sp != '\0') && (*sp !='.'))
  3912.       {
  3913.       sp++;
  3914.       }
  3915.  
  3916.    if (*sp == '.')
  3917.       {
  3918.       sp++;
  3919.       }
  3920.  
  3921.    if (IsHardClass(cbuff))
  3922.       {
  3923.       yyerror("Error in action sequence: %s\n",action);
  3924.       yyerror("You cannot add a reserved class!");
  3925.       return;
  3926.       }
  3927.  
  3928.    if (j == 1)
  3929.       {
  3930.       strcpy(actiontxt,cbuff);
  3931.       continue;
  3932.       }
  3933.    else if ((!IsSpecialClass(cbuff)) && (!IsItemIn(VALLADDCLASSES,cbuff)))
  3934.       {
  3935.       AppendItem(&VALLADDCLASSES,cbuff,NULL);
  3936.       }
  3937.    }
  3938. }
  3939.  
  3940. /*******************************************************************/
  3941.  
  3942. AppendToAccessList (user)
  3943.  
  3944. char *user;
  3945.  
  3946. { char id[maxvarsize];
  3947.   struct passwd *pw;
  3948.  
  3949. Debug1("Adding to access list for %s\n",user);
  3950.  
  3951. if (isalpha(user[0]))
  3952.    {
  3953.    if ((pw = getpwnam(user)) == NULL)
  3954.       {
  3955.       yyerror("No such user in password database");
  3956.       return;
  3957.       }
  3958.  
  3959.    sprintf(id,"%d",pw->pw_uid);
  3960.    AppendItem(&VACCESSLIST,id,NULL);
  3961.    }
  3962. else
  3963.    {
  3964.    AppendItem(&VACCESSLIST,user,NULL);
  3965.    }
  3966. }
  3967.  
  3968. /*******************************************************************/
  3969.  
  3970. HandleLinkAction(value)
  3971.  
  3972. char *value;
  3973.  
  3974. {
  3975. if (strcmp(value,"silent") == 0)
  3976.    {
  3977.    LINKSILENT = true;
  3978.    return;
  3979.    }
  3980.  
  3981. yyerror("Invalid link action");
  3982. }
  3983.  
  3984. /*******************************************************************/
  3985.  
  3986. HandleDeadLinks(value)
  3987.  
  3988. char *value;
  3989.  
  3990. {
  3991. if (strcmp(value,"kill") == 0)
  3992.    {
  3993.    DEADLINKS = false;
  3994.    return;
  3995.    }
  3996.  
  3997. if (strcmp(value,"force") == 0)
  3998.    {
  3999.    DEADLINKS = true;
  4000.    return;
  4001.    }
  4002.  
  4003. yyerror("Invalid deadlink option");
  4004. }
  4005.  
  4006. /*******************************************************************/
  4007.  
  4008. HandleLinkType(value)
  4009.  
  4010. char *value;
  4011.  
  4012. {
  4013. if (strcmp(value,"hard") == 0)
  4014.    {
  4015.    if (ACTION_IS_LINKCHILDREN)
  4016.       {
  4017.       yyerror("hard links inappropriate for multiple linkage");
  4018.       }
  4019.  
  4020.    if (ACTION == image)
  4021.       {
  4022.       yyerror("hard links inappropriate for copy operation");
  4023.       }
  4024.  
  4025.    LINKTYPE = 'h';
  4026.    return;
  4027.    }
  4028.  
  4029. if (strcmp(value,"symbolic") == 0 || strcmp(value,"sym") == 0)
  4030.    {
  4031.    LINKTYPE = 's';
  4032.    return;
  4033.    }
  4034.  
  4035. if (strcmp(value,"abs") == 0 || strcmp(value,"absolute") == 0)
  4036.    {
  4037.    LINKTYPE = 'a';
  4038.    return;
  4039.    }
  4040.  
  4041. if (strcmp(value,"rel") == 0 || strcmp(value,"relative") == 0)
  4042.    {
  4043.    LINKTYPE = 'r';
  4044.    return;
  4045.    }
  4046.  
  4047. if (strcmp(value,"none") == 0 || strcmp(value,"copy") == 0)
  4048.    {
  4049.    LINKTYPE = 'n';
  4050.    return;
  4051.    }
  4052.  
  4053.  sprintf(OUTPUT,"Invalid link type %s\n",value);
  4054. yyerror(OUTPUT);
  4055. }
  4056.  
  4057. /*******************************************************************/
  4058.  
  4059. HandleServer(value)
  4060.  
  4061. char *value;
  4062.  
  4063. {
  4064. Debug("Server in copy set to : %s\n",value);
  4065. strcpy(CFSERVER,value);
  4066. }
  4067.  
  4068. /*******************************************************************/
  4069.  
  4070. HandleDefine(value)
  4071.  
  4072. char *value;
  4073.  
  4074. { char *sp;
  4075.  
  4076. Debug("Define response classes: %s\n",value);
  4077.  
  4078. if (strlen(value) > bufsize)
  4079.    {
  4080.    yyerror("class list too long in copy action - can't handle it!");
  4081.    }
  4082.  
  4083. strcpy(ALLCLASSBUFFER,value);
  4084.  
  4085. for (sp = value; *sp != '\0'; sp++)
  4086.    {
  4087.    if (*sp == ':' || *sp == ',' || *sp == '.')
  4088.       {
  4089.       continue;
  4090.       }
  4091.    
  4092.    if (! isalnum(*sp) && *sp != '_')
  4093.       {
  4094.       sprintf(OUTPUT,"Illegal class list in define=%s\n",value);
  4095.       yyerror(OUTPUT);
  4096.       }
  4097.    }
  4098. }
  4099.  
  4100.  
  4101. /*******************************************************************/
  4102. /* Level 4                                                         */
  4103. /*******************************************************************/
  4104.  
  4105. struct UidList *MakeUidList(uidnames)
  4106.  
  4107. char *uidnames;
  4108.  
  4109. { struct UidList *uidlist;
  4110.   struct Item *ip, *tmplist;
  4111.   char uidbuff[bufsize];
  4112.   char *sp;
  4113.   int offset;
  4114.   struct passwd *pw;
  4115.   char *machine, *user, *domain, buffer[bufsize];
  4116.   int uid;
  4117.   int tmp;
  4118.  
  4119. uidlist = NULL;
  4120. buffer[0] = '\0';
  4121.  
  4122. ExpandVarstring(uidnames,buffer,"");
  4123.  
  4124. for (sp = buffer; *sp != '\0'; sp+=strlen(uidbuff))
  4125.    {
  4126.    if (*sp == ',')
  4127.       {
  4128.       sp++;
  4129.       }
  4130.  
  4131.    if (sscanf(sp,"%[^,]",uidbuff))
  4132.       {
  4133.       if (uidbuff[0] == '+')        /* NIS group - have to do this in a roundabout     */
  4134.          {                          /* way because calling getpwnam spoils getnetgrent */
  4135.          offset = 1;
  4136.          if (uidbuff[1] == '@')
  4137.             {
  4138.             offset++;
  4139.             }
  4140.  
  4141.          setnetgrent(uidbuff+offset);
  4142.          tmplist = NULL;
  4143.  
  4144.          while (getnetgrent(&machine,&user,&domain))
  4145.             {
  4146.             if (user != NULL)
  4147.                {
  4148.                AppendItem(&tmplist,user,NULL);
  4149.                }
  4150.             }
  4151.                    
  4152.          endnetgrent();
  4153.  
  4154.          for (ip = tmplist; ip != NULL; ip=ip->next)
  4155.             {
  4156.             if ((pw = getpwnam(ip->name)) == NULL)
  4157.                {
  4158.            sprintf(OUTPUT,"Unknown user [%s]\n",ip->name);
  4159.            CfLog(cfverbose,OUTPUT,"getpwnam");
  4160.                continue;
  4161.                }
  4162.             else
  4163.                {
  4164.                uid = pw->pw_uid;
  4165.                }
  4166.             AddSimpleUidItem(&uidlist,uid); 
  4167.             }
  4168.  
  4169.          DeleteItemList(tmplist);
  4170.          continue;
  4171.          }
  4172.  
  4173.       if (isdigit(uidbuff[0]))
  4174.          {
  4175.          sscanf(uidbuff,"%d",&tmp);
  4176.          uid = (uid_t)tmp;
  4177.          }
  4178.       else
  4179.          {
  4180.          if (strcmp(uidbuff,"*") == 0)
  4181.             {
  4182.             uid = -1;                     /* signals wildcard */
  4183.             }
  4184.          else if ((pw = getpwnam(uidbuff)) == NULL)
  4185.             {
  4186.             printf("Unknown user %s\n",uidbuff);
  4187.             Warning("User is not known in this passwd domain");
  4188.             continue;
  4189.             }
  4190.          else
  4191.             {
  4192.             uid = pw->pw_uid;
  4193.             }
  4194.          }
  4195.       AddSimpleUidItem(&uidlist,uid);
  4196.       }
  4197.    }
  4198.  
  4199. if (uidlist == NULL)
  4200.    {
  4201.    AddSimpleUidItem(&uidlist,(uid_t) -1);
  4202.    }
  4203.  
  4204. return (uidlist);
  4205. }
  4206.  
  4207. /*********************************************************************/
  4208.  
  4209. struct GidList *MakeGidList(gidnames)
  4210.  
  4211. char *gidnames;
  4212.  
  4213. { struct GidList *gidlist;
  4214.   char gidbuff[bufsize],buffer[bufsize];
  4215.   char err[bufsize];
  4216.   char *sp;
  4217.   struct group *gr;
  4218.   int gid;
  4219.   int tmp;
  4220.  
  4221. gidlist = NULL;
  4222. buffer[0] = '\0';
  4223.  
  4224. ExpandVarstring(gidnames,buffer,"");
  4225.  
  4226. for (sp = buffer; *sp != '\0'; sp+=strlen(gidbuff))
  4227.    {
  4228.    if (*sp == ',')
  4229.       {
  4230.       sp++;
  4231.       }
  4232.  
  4233.    if (sscanf(sp,"%[^,]",gidbuff))
  4234.       {
  4235.       if (isdigit(gidbuff[0]))
  4236.          {
  4237.          sscanf(gidbuff,"%d",&tmp);
  4238.          gid = (gid_t)tmp;
  4239.          }
  4240.       else
  4241.          {
  4242.          if (strcmp(gidbuff,"*") == 0)
  4243.             {
  4244.             gid = -1;                     /* signals wildcard */
  4245.             }
  4246.          else if ((gr = getgrnam(gidbuff)) == NULL)
  4247.             {
  4248.             sprintf(err,"Unknown group %s\n",gidbuff);
  4249.             Warning(err);
  4250.             continue;
  4251.             }
  4252.          else
  4253.             {
  4254.             gid = gr->gr_gid;
  4255.             }
  4256.          }
  4257.       AddSimpleGidItem(&gidlist,gid);
  4258.       }
  4259.    }
  4260.  
  4261. if (gidlist == NULL)
  4262.    {
  4263.    AddSimpleGidItem(&gidlist,(gid_t) -1);
  4264.    }
  4265.  
  4266. return(gidlist);
  4267. }
  4268.  
  4269.  
  4270. /*******************************************************************/
  4271.  
  4272. InstallTidyPath(path,wild,rec,age,travlinks,tidysize,type,ldirs,tidydirs,classes,defines)
  4273.  
  4274. char *wild, *path, *defines;
  4275. short age,tidydirs;
  4276. int rec, tidysize;
  4277. char type, ldirs, *classes, travlinks;
  4278.  
  4279. { struct Tidy *ptr;
  4280.   char *sp;
  4281.   int no_of_links = 0;
  4282.  
  4283. if (!IsInstallable(classes))
  4284.    {
  4285.    InitializeAction();
  4286.    Debug1("Not installing tidy path, no match\n");
  4287.    return;
  4288.    }
  4289.  
  4290. VBUFF[0]='\0';                                /* Expand any variables */
  4291. ExpandVarstring(path,VBUFF,"");
  4292.  
  4293. if (strlen(VBUFF) != 1)
  4294.    {
  4295.    DeleteSlash(VBUFF);
  4296.    }
  4297.  
  4298. if ((ptr = (struct Tidy *)malloc(sizeof(struct Tidy))) == NULL)
  4299.    {
  4300.    FatalError("Memory Allocation failed for InstallTidyItem() #1");
  4301.    }
  4302.  
  4303. if ((ptr->path = strdup(VBUFF)) == NULL)
  4304.    {
  4305.    FatalError("Memory Allocation failed for InstallTidyItem() #3");
  4306.    }
  4307.  
  4308. if (VTIDYTOP == NULL)                 /* First element in the list */
  4309.    {
  4310.    VTIDY = ptr;
  4311.    }
  4312. else
  4313.    {
  4314.    VTIDYTOP->next = ptr;
  4315.    }
  4316.  
  4317. if (rec != INFINITERECURSE && strncmp("home/",ptr->path,5) == 0) /* Is this a subdir of home wildcard? */
  4318.    {
  4319.    for (sp = ptr->path; *sp != '\0'; sp++)                     /* Need to make recursion relative to start */
  4320.       {                                                        /* of the search, not relative to home */
  4321.       if (*sp == '/')
  4322.          {
  4323.          no_of_links++;
  4324.          }
  4325.       }
  4326.    }
  4327.  
  4328. ptr->tidylist = NULL;
  4329. ptr->recurse = rec + no_of_links;
  4330. ptr->next = NULL;
  4331.  
  4332. VTIDYTOP = ptr;
  4333.  
  4334. AddTidyItem(path,wild,rec,age,travlinks,tidysize,type,ldirs,tidydirs,classes,defines);
  4335. }
  4336.  
  4337. /*********************************************************************/
  4338.  
  4339. AddTidyItem(path,wild,rec,age,travlinks,tidysize,type,ldirs,tidydirs,classes,defines)
  4340.  
  4341. char *wild, *path, *defines;
  4342. short age,tidydirs;
  4343. int rec,tidysize;
  4344. char type, ldirs,*classes, travlinks;
  4345.  
  4346. { char varbuff[bufsize];
  4347.   struct Tidy *ptr;
  4348.  
  4349. Debug1("AddTidyItem(%s,pat=%s,size=%d)\n",path,wild,tidysize);
  4350.  
  4351. if ( ! IsInstallable(CLASSBUFF))
  4352.    {
  4353.    InitializeAction();
  4354.    Debug1("Not installing TidyItem no match\n");
  4355.    return;
  4356.    }
  4357.  
  4358. for (ptr = VTIDY; ptr != NULL; ptr=ptr->next)
  4359.    {
  4360.    varbuff[0] = '\0';
  4361.    ExpandVarstring(path,varbuff,"");
  4362.  
  4363.    if (strcmp(ptr->path,varbuff) == 0)
  4364.       {
  4365.       PrependTidy(&(ptr->tidylist),wild,rec,age,travlinks,tidysize,type,ldirs,tidydirs,classes,defines);
  4366.       
  4367.       /* Must have the maximum recursion level here */
  4368.       
  4369.       if (rec == INFINITERECURSE || (ptr->recurse < rec && ptr->recurse != INFINITERECURSE))
  4370.      {
  4371.          ptr->recurse = rec;
  4372.      }
  4373.       return;
  4374.       }
  4375.    }
  4376. }
  4377.  
  4378. /*********************************************************************/
  4379.  
  4380. TidyPathExists(path)
  4381.  
  4382. char *path;
  4383.  
  4384. { struct Tidy *tp;
  4385.  
  4386. VBUFF[0]='\0';                                /* Expand any variables */
  4387. ExpandVarstring(path,VBUFF,"");
  4388.  
  4389. for (tp = VTIDY; tp != NULL; tp=tp->next)
  4390.    {
  4391.    if (strcmp(tp->path,path) == 0)
  4392.       {
  4393.       Debug1("TidyPathExists(%s)\n",path);
  4394.       return true;
  4395.       }
  4396.    }
  4397.  
  4398. return false;
  4399. }
  4400.  
  4401.  
  4402. /*******************************************************************/
  4403. /* Level 5                                                         */
  4404. /*******************************************************************/
  4405.  
  4406. AddSimpleUidItem(uidlist,uid)
  4407.  
  4408. struct UidList **uidlist;
  4409. int uid;
  4410.  
  4411. { struct UidList *ulp, *u;
  4412.  
  4413. if ((ulp = (struct UidList *)malloc(sizeof(struct UidList))) == NULL)
  4414.    {
  4415.    FatalError("cfengine: malloc() failed #1 in AddSimpleUidItem()");
  4416.    }
  4417.  
  4418. ulp->uid = uid;
  4419. ulp->next = NULL;
  4420.  
  4421. if (*uidlist == NULL)
  4422.    {
  4423.    *uidlist = ulp;
  4424.    }
  4425. else
  4426.    {
  4427.    for (u = *uidlist; u->next != NULL; u = u->next)
  4428.       {
  4429.       }
  4430.    u->next = ulp;
  4431.    }
  4432. }
  4433.  
  4434. /*******************************************************************/
  4435.  
  4436. AddSimpleGidItem(gidlist,gid)
  4437.  
  4438. struct GidList **gidlist;
  4439. int gid;
  4440.  
  4441. { struct GidList *glp,*g;
  4442.  
  4443. if ((glp = (struct GidList *)malloc(sizeof(struct GidList))) == NULL)
  4444.    {
  4445.    FatalError("cfengine: malloc() failed #1 in AddSimpleGidItem()");
  4446.    }
  4447.  
  4448. glp->gid = gid;
  4449. glp->next = NULL;
  4450.  
  4451. if (*gidlist == NULL)
  4452.    {
  4453.    *gidlist = glp;
  4454.    }
  4455. else
  4456.    {
  4457.    for (g = *gidlist; g->next != NULL; g = g->next)
  4458.       {
  4459.       }
  4460.    g->next = glp;
  4461.    }
  4462. }
  4463.  
  4464.  
  4465. /***********************************************************************/
  4466.  
  4467. InstallAuthPath(path,hostname,classes,list,listtop)
  4468.  
  4469. char *path, *hostname, *classes;
  4470. struct Auth **list, **listtop;
  4471.  
  4472. { struct Auth *ptr;
  4473.  
  4474. if (!IsInstallable(classes))
  4475.    {
  4476.    Debug1("Not installing Auth path, no match\n");
  4477.    return;
  4478.    }
  4479.  
  4480. Debug1("InstallAuthPath(%s,%s)\n",path,hostname);
  4481.  
  4482. VBUFF[0]='\0';                                /* Expand any variables */
  4483. ExpandVarstring(path,VBUFF,"");
  4484.  
  4485. if (strlen(VBUFF) != 1)
  4486.    {
  4487.    DeleteSlash(VBUFF);
  4488.    }
  4489.  
  4490. if ((ptr = (struct Auth *)malloc(sizeof(struct Auth))) == NULL)
  4491.    {
  4492.    FatalError("Memory Allocation failed for InstallAuthPath() #1");
  4493.    }
  4494.  
  4495. if ((ptr->path = strdup(VBUFF)) == NULL)
  4496.    {
  4497.    FatalError("Memory Allocation failed for InstallAuthPath() #3");
  4498.    }
  4499.  
  4500. if (*listtop == NULL)                 /* First element in the list */
  4501.    {
  4502.    *list = ptr;
  4503.    }
  4504. else
  4505.    {
  4506.    (*listtop)->next = ptr;
  4507.    }
  4508.  
  4509. ptr->accesslist = NULL;
  4510. ptr->maproot = NULL;
  4511. ptr->secure = false; 
  4512. ptr->next = NULL;
  4513. *listtop = ptr;
  4514.  
  4515. AddAuthHostItem(ptr->path,hostname,classes,list);
  4516. }
  4517.  
  4518. /***********************************************************************/
  4519.  
  4520. AddAuthHostItem(path,attribute,classes,list)
  4521.  
  4522. char *path, *attribute, *classes;
  4523. struct Auth **list;
  4524.  
  4525. { char varbuff[bufsize];
  4526.   struct Auth *ptr;
  4527.  
  4528. Debug1("AppendAuthHostItem(%s,%s)\n",path,attribute);
  4529.  
  4530. if (!IsInstallable(CLASSBUFF))
  4531.    {
  4532.    Debug1("Not installing TidyItem no match\n");
  4533.    return;
  4534.    }
  4535.  
  4536. for (ptr = *list; ptr != NULL; ptr=ptr->next)
  4537.    {
  4538.    varbuff[0] = '\0';
  4539.    ExpandVarstring(path,varbuff,"");
  4540.  
  4541.    if (strcmp(ptr->path,varbuff) == 0)
  4542.       {
  4543.       if (!HandleAdmitAttribute(ptr,attribute))
  4544.      {
  4545.      PrependItem(&(ptr->accesslist),attribute,classes);
  4546.      }
  4547.       return;
  4548.       }
  4549.    }
  4550. }
  4551.  
  4552.  
  4553. /*********************************************************************/
  4554.  
  4555. AuthPathExists(path,list)
  4556.  
  4557. char *path;
  4558. struct Auth *list;
  4559.  
  4560. { struct Auth *ap;
  4561.  
  4562. Debug1("AuthPathExists(%s)\n",path);
  4563.  
  4564. VBUFF[0]='\0';                                /* Expand any variables */
  4565. ExpandVarstring(path,VBUFF,"");
  4566.  
  4567. if (VBUFF[0] != '/')
  4568.    {
  4569.    yyerror("Missing absolute path to a directory");
  4570.    FatalError("Cannot continue");
  4571.    }
  4572.  
  4573. for (ap = list; ap != NULL; ap=ap->next)
  4574.    {
  4575.    if (strcmp(ap->path,VBUFF) == 0)
  4576.       {
  4577.       return true;
  4578.       }
  4579.    }
  4580.  
  4581. return false;
  4582. }
  4583.  
  4584. /*********************************************************************/
  4585.  
  4586. HandleAdmitAttribute(ptr,attribute)
  4587.  
  4588. struct Auth *ptr;
  4589. char *attribute;
  4590.  
  4591. { char value[maxvarsize],buffer[bufsize],host[maxvarsize],*sp;
  4592.  
  4593. VBUFF[0] = value[0] = '\0';
  4594.  
  4595. ExpandVarstring(attribute,VBUFF,NULL);
  4596.  
  4597. sscanf(VBUFF,"%*[^=]=%s",value);
  4598.  
  4599. if (value[0] == '\0')
  4600.    {
  4601.    return false;
  4602.    }
  4603.  
  4604. Debug1("HandleOptionalFileAttribute(%s)\n",value);
  4605.  
  4606. switch(GetCommAttribute(attribute))
  4607.    {
  4608.    case cfsecure:  if ((strcmp(value,"on")==0) || (strcmp(value,"true")==0))
  4609.                       {
  4610.               ptr->secure = true;
  4611.               return true;
  4612.               }
  4613.                    break;
  4614.  
  4615.    case cfroot:   bzero(buffer,bufsize);
  4616.  
  4617.                   ExpandVarstring(value,buffer,"");
  4618.  
  4619.           for (sp = buffer; *sp != '\0'; sp+=strlen(host))
  4620.              {
  4621.              if (*sp == ',')
  4622.             {
  4623.             sp++;
  4624.             }
  4625.  
  4626.              host[0] = '\0';
  4627.              
  4628.              if (sscanf(sp,"%[^,]",host))
  4629.             {
  4630.             if (!strstr(host,"."))
  4631.                {
  4632.                if (strlen(host)+strlen(VDOMAIN) < maxvarsize-2)
  4633.                   {
  4634.                   strcat(host,".");
  4635.                   strcat(host,VDOMAIN);
  4636.                   }
  4637.                else
  4638.                   {
  4639.                   yyerror("Server name too long");
  4640.                   }
  4641.                }
  4642.             PrependItem(&(ptr->maproot),host,NULL);
  4643.             }
  4644.              }
  4645.           return true;
  4646.           break;
  4647.    }
  4648.  
  4649. yyerror("Illegal admit attribute"); 
  4650. return false;
  4651. }
  4652.  
  4653.  
  4654. /*********************************************************************/
  4655.  
  4656. PrependTidy(list,wild,rec,age,travlinks,tidysize,type,ldirs,tidydirs,classes,defines)
  4657.  
  4658. struct TidyPattern **list;
  4659. char *wild;
  4660. short age,tidydirs;
  4661. int rec,tidysize;
  4662. char type, ldirs, *classes, *defines, travlinks;
  4663.  
  4664. { struct TidyPattern *tp;
  4665.   char *spe,*sp, buffer[bufsize];
  4666.  
  4667. if ((tp = (struct TidyPattern *)malloc(sizeof(struct TidyPattern))) == NULL)
  4668.    {
  4669.    perror("Can't allocate memory in PrependTidy()");
  4670.    FatalError("");
  4671.    }
  4672.  
  4673. if ((sp = strdup(wild)) == NULL)
  4674.    {
  4675.    FatalError("Memory Allocation failed for PrependTidy() #2");
  4676.    }
  4677.  
  4678. bzero(buffer,bufsize);
  4679. ExpandVarstring(defines,buffer,""); 
  4680.  
  4681. if ((tp->defines = strdup(buffer)) == NULL)
  4682.    {
  4683.    FatalError("Memory Allocation failed for PrependTidy() #2a");
  4684.    }
  4685.  
  4686. AddInstallable(tp->defines); 
  4687.  
  4688. if ((classes!= NULL) && (spe = malloc(strlen(classes)+2)) == NULL)
  4689.    {
  4690.    perror("Can't allocate memory in PrependItem()");
  4691.    FatalError("");
  4692.    }
  4693.  
  4694. if (travlinks == '?')
  4695.    {
  4696.    travlinks = 'F';  /* False is default */
  4697.    }
  4698.  
  4699. tp->size = tidysize;
  4700. tp->recurse = rec;
  4701. tp->age = age;
  4702. tp->searchtype = type;
  4703. tp->travlinks = travlinks;
  4704. tp->pattern = sp;
  4705. tp->next = *list;
  4706. tp->dirlinks = ldirs;
  4707. tp->log = LOGP;
  4708. tp->inform = INFORMP;
  4709.  
  4710. switch (tidydirs)
  4711.    {
  4712.    case 0: tp->rmdirs = 'f';
  4713.            break;
  4714.    case 1: tp->rmdirs = 't';
  4715.            break;
  4716.    case 2: tp->rmdirs = 's';
  4717.            break;
  4718.    default: FatalError("Software error in Prepend Tidy");
  4719.    }
  4720.  
  4721. *list = tp;
  4722.  
  4723. if (classes != NULL)
  4724.    {
  4725.    strcpy(spe,classes);
  4726.    tp->classes = spe;
  4727.    }
  4728. else
  4729.    {
  4730.    tp->classes = NULL;
  4731.    }
  4732. }
  4733.  
  4734. /* EOF */
  4735.